Skip to content

Releases: tmc/go-iroh

v0.3.0

Choose a tag to compare

@tmc tmc released this 01 Oct 01:23
22573d6

Behaviour and interoperability release. Nothing was removed and no exported signature changed.

Added: seven blob chunk-range APIs, docs.InsertOutcome.Err, blobs.Downloader.Wait, and blobs.ErrDownloaderClosed. Adding Err and Wait can make selectors ambiguous on types embedding another provider of the same method.

Four behaviour changes worth reading before upgrading.

  • Incoming docs sync requires authorization. A nil docs.Handler.Allow used to permit every peer and namespace; it now rejects every request with AbortNotFound, including legacy handshakes. Supply an explicit namespace and peer policy. Handler.Validate adds policy after mandatory signature and empty-record checks; it cannot bypass them.
  • Closing a downloader ends its work. Close rejects new downloads, cancels active ones, and closes cached connections. Wait(ctx) joins downloads and their callbacks. An OnEvent callback may call Close, but must not call Wait. New downloads after closure return ErrDownloaderClosed.
  • Save failures reach callers. Check InsertOutcome.Err(). Failed saves leave entries readable in memory, but sync reports failure until persistence succeeds. Duplicate inserts retry a failed save. Mutations, saves, and subscriber events are ordered.
  • Live sync closure waits for workers and callbacks. An OnSync callback must arrange Close asynchronously rather than call it itself.

Blob providers now serve arbitrary chunk selections, hash-sequence children, and bao-tree-compatible partial-block proofs. Use the new chunk APIs for iroh-blobs wire responses; the byte-offset EncodeBlobRange retains whole-group encoding.

Docs sync opens with Init, matching iroh-docs, while accepting older report-first clients under the explicit policy. Live sync downloads reconciled content, retains queued work during bursts, and recovers subscriber lag. Cancellation interrupts blocked sync I/O; canceling a blob download preserves connections shared by other transfers.

mDNS puts addresses in the additional section, omits empty TXT records, and resolves every SRV record for an instance. NAT traversal rounds start only on client connections.

The Rust parity matrix records 34 passes and one expected postcard-varint incompatibility per pinned release, iroh 1.2.0 and 1.3.0. Docs interop uses a separate iroh 1.1.0 peer. See COMPATIBILITY.md for scope, provenance, and the full detail.

v0.2.3

Choose a tag to compare

@tmc tmc released this 30 Sep 08:24
v0.2.3
0d0d956

What's Changed

  • relayclient: support Relay proxies in #34
  • iroh: bound incoming handshakes in #32
  • gossip: per-peer send queues in #33
  • endpointticket: match Rust IPv6 address encoding in #36
  • gossip, iroh: bound peer data, missing messages, and session keys in #37
  • docs: pass the sync's context to content status in #38
  • gossip: re-send Join until a neighbor is up in #39

Full Changelog: v0.2.2...v0.2.3

v0.2.2

Choose a tag to compare

@tmc tmc released this 29 Sep 03:56
v0.2.2
956be2c

Security and robustness release. Nothing was removed and no exported signature changed.

Added: docs.MemoryStore.InitialMessageInNamespace and ProcessMessageInNamespace.

Deprecated: InitialMessage and ProcessMessage, which still compile and still reconcile across every namespace in the store.

Most of this release closes ways a remote peer could make an endpoint do or reveal more than it should.

  • docs sync is confined to the negotiated namespace. A round used to reconcile every namespace in the store after authorizing one, and live sync broadcast inserts from namespaces neighbors never asked for. Sync frames are now capped at 16 MiB (was 1 GiB), buffers grow only as bytes arrive, and remote entries dated past MaxTimestampFutureShift are rejected.
  • relayserver sends departure notices only to peers the departing session sent to. Any connected client could previously learn the identity of every endpoint that disconnected.
  • Bounded reads and caches. pkarr relay responses are limited to MaxSignedPacketSize. Blob downloads check for trailing data by reading one byte instead of draining the stream. The socket's received-address cache is capped.
  • Frame lengths that do not fit in an int are rejected in irpc and gossip. On 32-bit platforms such a length became negative and passed the size check.
  • A stream listener survives a rejected peer. One handshake rejected by an AfterHandshake hook used to stop ListenStreams for every peer (#25). Thanks to @carsonfarmer for the report and the regression test in #26.

Three gossip fixes, each a case where a peer stayed subscribed to a topic but was never connected to it. A Join or ForwardJoin from a peer we had already answered once went unanswered, so its new subscription never saw NeighborUp. Closing a topic left its old neighbors in Neighbors and IsJoined after a resubscribe.

The docs changes are visible on the wire. A go-iroh peer never sends a frame larger than it accepts, and rejects entries dated too far in the future.

v0.2.1

Choose a tag to compare

@tmc tmc released this 16 Sep 04:44
v0.2.1
a35426d

Patch release. Nothing was removed and no exported signature changed.

iroh.ConnStats gained PTOs and SpuriousLosses. Adding fields to an exported struct breaks unkeyed composite literals; keyed literals are unaffected.

  • A wildcard-bound endpoint now replies from the address a peer's datagrams arrived at, not whichever address the route picks. They differ on a multi-homed host or behind a bridge or container network, where a QUIC peer receiving packets from an address it never dialed fails path validation.
  • Connect starts a handshake per dial target 250 ms apart and takes the first that completes, instead of walking them in turn. Unreachable direct addresses no longer cost a handshake timeout each before the relay path is tried.
  • Path selection re-runs once a hole punch succeeds. A relay-to-direct upgrade that took about five seconds now takes tens of milliseconds.

On Linux the receive path uses UDP_GRO. Nothing changes on the wire, and other platforms keep the per-packet loop.

Three loss-recovery fixes in the vendored internal/qng, each a case where a connection could stall on a timer that was never set. golang.org/x/crypto moved to v0.56.0, clearing three unreachable govulncheck advisories.

See COMPATIBILITY.md for the full detail.

v0.2.0

Choose a tag to compare

@tmc tmc released this 08 Sep 01:52
f3a4704

Behaviour release. Nothing was removed and no exported signature changed.

Added: iroh.WithoutNetReport. Deprecated: iroh.WithNetReport — it still compiles and still clears the disable flag, so passing it is harmless, but it no longer enables anything that was off.

Four behaviour changes worth reading before upgrading.

  • net_report runs by default whenever relays are configured. Such an endpoint sends probes it did not send before, and its home relay can move away from the bootstrap pick after Bind. iroh.WithoutNetReport turns it off.
  • Path MTU discovery runs. Setting the don't-fragment bit had been gated behind an IROH_ENABLE_DF environment variable, so an accepting endpoint stayed at the initial 1243-byte payload for the life of the connection. Datagrams too large for the path now fail with EMSGSIZE rather than being fragmented, which is what QUIC requires.
  • mdns answers SRV and TXT questions, which were previously dropped, and discovers over the IPv6 multicast group ff02::fb as well as IPv4. An SRV or TXT question must name the instance rather than the service.
  • relay.Map is safe for concurrent use and must not be copied after first use. Both fields were already unexported, so no composite literal is affected; copying a Map by value now trips go vet's copylocks check.

The vendored quic-go fork in internal/qng was updated to upstream v0.62.0, by way of v0.61.0. That package is internal, so no exported API changed.

See COMPATIBILITY.md for the full detail, including measured performance, and the Rust parity matrix.

v0.1.1

Choose a tag to compare

@tmc tmc released this 05 Sep 00:57
v0.1.1
8c960d2

Additive release. Nothing was removed and no exported signature changed.

Added: iroh.Stream.CloseWrite, iroh.ErrTLSHandshakeFailure,
iroh.QLOGConnection, iroh.QLOGDir, iroh.WithQLOG, mdns.WithLogger,
key.UncheckedEndpointID, relayserver.NewWithOptions, relayserver.Option,
relayserver.WithClientRate.

Two encoding changes worth reading before upgrading. u8 and i8 now encode as one raw byte, matching Rust postcard. A u8 below 128 is unaffected, but i8 changes for every value except zero, so persisted signed 8-bit postcard
data does not survive the upgrade. Padded varints are now rejected — stricter than postcard 1.1.3, which accepts them.

Two source-level breaks gossip.Event gained a Dropped field, so unkeyed composite literals of it no longer compile; keyed literals are unaffected. iroh.Stream gained a CloseWrite method, which makes the selector ambiguous for a type embedding Stream alongside another type that also provides CloseWrite.

See COMPATIBILITY.md for the Rust parity matrix and the full detail.

v0.1.0

Choose a tag to compare

@tmc tmc released this 20 Aug 01:56
v0.1.0
e74201f

go-iroh v0.1.0

Breaking changes

Before v0.1.0
Store.Get(ctx, hash) (MapEntry, bool, error) Store.Open(ctx, hash) (Blob, error)
FSStore.GetBlob(hash) ([]byte, bool) blobs.ReadBlob(ctx, store, hash) ([]byte, error)
BytesMap / NewBytesMap MemStore / NewMemStore
MapEntry Blob

go-iroh v0.1.0 upgrade

Use Go 1.26 or later. Start from a clean worktree:

go get github.com/tmc/go-iroh@v0.0.2
go fix -diff -inline ./...
go fix -inline ./...
go get github.com/tmc/go-iroh@v0.1.0
go mod tidy
go build ./...
go test -count=1 ./...

note: Use -inline explicitly: plain go fix also applies unrelated Go modernizers.