Changelog

July 29, 2026 · View on GitHub

All notable changes to this project will be documented in this file.

Note:

Legend

The following emojis are used to highlight certain changes:

  • 🛠 - BREAKING CHANGE. Action is required if you use this functionality.
  • ✨ - Noteworthy change to be aware of.

[Unreleased]

Added

Changed

Removed

Fixed

Security

[v0.16.0] - 2026-07-29

Added

  • someguy now replaces a /dnsaddr provider address with the addresses it names, before it applies filter-addrs. A /dnsaddr carries no transport component, so a filter could neither match nor exclude it: a provider reachable only through a /dnsaddr was dropped from a filtered response, and a provider the client asked to exclude survived one. someguy resolves on every request by default. A request that sends filter-addrs gets the /dnsaddr replaced, since keeping it would let a record survive a filter meant to exclude it (unless a positive filter entry names dnsaddr, the one filter that can match it; then the /dnsaddr is kept). A request without a filter gets the resolved addresses added and keeps the /dnsaddr, so it can dial straight away and still re-resolve later. Set SOMEGUY_DNSADDR_RESOLUTION=replace to drop the /dnsaddr from unfiltered responses too, filtered to skip the lookup for unfiltered requests, or never to disable it (the default is append). Lookups are cached and bounded per request, watched by two new metrics: someguy_routers_dnsaddr_resolutions and someguy_routers_dnsaddr_resolution_duration_seconds. See docs/dnsaddr-resolution.md. #174
  • Addresses within a record are now ordered by how directly a client can dial them: IP first, then DNS names, then /dnsaddr, with /p2p-circuit relays last. #174

Changed

[v0.15.0] - 2026-07-27

Added

  • Background FindPeer lookups, the ones someguy dispatches for provider records that arrive without addresses, are now capped at 512 concurrent per instance. These lookups outlive the request that triggered them, so a client could close its connection and leave a full DHT walk running, with nothing bounding how many piled up. Measured on delegated-ipfs.dev an instance runs on the order of 20 at once, so the cap only engages far outside normal traffic. Three metrics were added to watch it: someguy_cached_router_find_peer_lookups_in_flight, someguy_cached_router_find_peer_lookups_rejected, and someguy_cached_router_find_peer_lookup_duration_seconds. Tune with SOMEGUY_CACHED_ADDR_BOOK_MAX_CONCURRENT_FIND_PEERS. #169
  • SOMEGUY_ROUTING_TIMEOUT sets how long one /routing/v1 request may spend in the routers, defaulting to 25s. It has to stay below the timeout clients put on the whole request, otherwise a client gives up before someguy flushes and every record someguy resolved is lost. #169

Changed

  • boxo (main, past v0.42.0) and go-libp2p-kad-dht v0.42.1 #171
  • someguy now shuts the DHT down explicitly. Its constructors stopped taking a context in go-libp2p-kad-dht v0.42.0, so cancelling the context that built them no longer stops their long-lived goroutines. SIGTERM now closes both the standard and accelerated clients before someguy exits. #171
  • /routing/v1 responses no longer let a cache serve a two-day-old answer while someguy is healthy. stale-while-revalidate is now 10 minutes for responses with results and 1 minute for empty ones, which covers a background refresh. stale-if-error only applies when someguy is failing, so responses with results keep the 48h Amino DHT expiration window, and empty ones drop to 1 hour. max-age is unchanged. The addresses someguy returns come from short-lived sources such as relay reservations, so a stale window measured in days handed clients addresses that had stopped working long ago. ipfs/boxo#1195

Fixed

  • Accept: application/x-ndjson responses now reach the client as each record is produced, instead of arriving in one batch at the end. Response compression was holding writes back until 200 bytes had accumulated, and a provider record is often smaller than that, so a provider someguy had already resolved sat in a buffer while it looked up the rest. Clients that give up before someguy finishes, such as Helia's delegated routing client with its 30s deadline, saw an empty result even though providers had been found. Response headers were withheld the same way, so the request appeared to hang. #169
  • someguy now stops its routing lookups at 25s rather than 30s, so it finishes and flushes before clients that bound the whole request at 30s walk away. Results found near the deadline now reach the client instead of being discarded with the aborted request. #169

[v0.14.1] - 2026-07-14

Fixed

  • someguy now expires /p2p-circuit (relay) addresses from its cache much sooner than direct ones. A relay reservation is short-lived: it lasts at most an hour and is dropped the moment the peer disconnects from the relay, so a relay address kept for the usual 48 hours is often long dead by the time a client dials it. Relay addresses now use a shorter TTL (twice the relay reservation TTL by default) and are renewed only while the peer stays reachable, so working relay paths survive and dead ones age out within hours instead of days. See docs/peer-address-caching.md.
  • /routing/v1 responses now list direct addresses before /p2p-circuit (relay) addresses. A client that dials addresses in order reaches a directly dialable one first and only falls back to a relay, which is slower and exists mainly to bootstrap a direct connection.

[v0.14.0] - 2026-06-08

Changed

Fixed

  • GetIPNS no longer returns an IPNS record whose EOL has already passed. An expired record is cryptographically invalid, so it is treated as not found, and when multiple routers answer the first non-expired record is returned. #154
  • /routing/v1/ipns/{name} no longer gives a cache a freshness window that outlives the record. It caps max-age to the record's remaining validity and sizes the stale-while-revalidate/stale-if-error window to fit within its EOL. An expired record, or one without an EOL validity, returns Cache-Control: no-store. #155
  • /routing/v1/peers/{peerid} now serves addresses cache-first, the same way /routing/v1/providers/{cid} does. It answers from the cached address book and host peerstore before falling back to a DHT lookup, so a relay-dependent peer that is absent from peer routing but recently seen as a provider is no longer answered with an empty result. See docs/peer-address-caching.md. #153
  • A completed identify now prunes a peer's cached addresses down to its current advertised set (signed peer record or identify listen addresses) plus any live-connection address, instead of unioning forever. This stops stale certhashes, dead relay circuits, and rotated NAT ports from accumulating across provider lookups and gossip. #153
  • Multiaddrs in /routing/v1 responses are returned in a stable sorted order. They previously came back in nondeterministic order, so repeated requests for the same peer or provider returned the same addresses shuffled differently. #153

Security

  • The OpenTelemetry OTLP HTTP exporter now caps response bodies at 4 MiB, so a hostile or man-in-the-middle collector cannot exhaust someguy's memory (CVE-2026-39882). The gRPC exporter was never affected. #155

[v0.13.0] - 2026-05-26

Added

  • --records-limit / SOMEGUY_RECORDS_LIMIT (default 100) caps results for Accept: application/json, matching the SHOULD-cap in HTTP Routing v1 §4.1.5. Set to 0 to disable the cap. #150
  • --streaming-records-limit / SOMEGUY_STREAMING_RECORDS_LIMIT (default 1000) caps results for Accept: application/x-ndjson. Set to 0 to disable the cap. #150

Changed

Fixed

  • JSON delegated routing requests now surface close to the requested number of providers. The boxo server enforces the records limit after filtering, so records without addresses no longer shrink the response below --records-limit. #150

[v0.12.0] - 2026-04-24

Changed

  • boxo v0.39.0
  • go-libp2p v0.48.0
  • go-libp2p-kad-dht v0.39.1
  • bumped Docker workflow actions (setup-qemu-action, setup-buildx-action, login-action, build-push-action) to latest majors
  • Docker image builder bumped to golang:1.26-bookworm
  • clearer --help descriptions for someguy, someguy start, and someguy ask (including per-subcommand short descriptions and correct USAGE lines)
  • README, docs/environment-variables.md, docs/metrics.md, and docs/tracing.md rewritten for clarity (active voice, removed duplicated wording)

Fixed

  • docs/environment-variables.md: replaced the self-referential default for SOMEGUY_LIBP2P_LISTEN_ADDRS with a pointer to someguy start --help so the docs cannot drift from the CLI default
  • docs/metrics.md: fixed "Prometheus Glient" typo, corrected plural/subject-verb agreement, and documented the previously-undocumented someguy_cached_addr_book_probed_peers counter
  • docs/tracing.md: corrected the example port (80908190, matching SOMEGUY_LISTEN_ADDRESS default), replaced broken headers.md links with inline descriptions, and clarified that tracing covers inbound HTTP routing requests (not "gateway" requests)

[v0.11.1]

Changed

[v0.11.0] - 2025-11-20

Added

  • Added support for IPIP-476: /routing/v1/peers/closest/{key} endpoint for finding DHT-closest peers (#124, #127)
    • Returns DHT-closest peers to a given CID or PeerID
    • Accepts both CID and legacy PeerID formats (e.g., 12D3KooW...)
    • Uses WAN DHT only for more reliable results
    • Includes cached addresses in results when available
    • Properly returns HTTP 500 when DHT is disabled
  • AutoConf support: automatic configuration of bootstrap peers and delegated routing endpoints (#123). When enabled (default), the auto placeholder is replaced with network-recommended values.
    • All endpoint flags (--provider-endpoints, --peer-endpoints, --ipns-endpoints) default to auto
    • See environment-variables.md for configuration details

Changed

Removed

Fixed

  • Fixed multiple race conditions and deadlocks in iterator implementations (#119)

Security

[v0.10.0]

Added

  • Automatic generation of peer IDs for HTTP block providers when not explicitly configured (#117)
    • When SOMEGUY_HTTP_BLOCK_PROVIDER_ENDPOINTS are configured but no SOMEGUY_HTTP_BLOCK_PROVIDER_PEERIDS are configured, synthetic PeerIDs will now be autogenerated. These are deterministic placeholders derived from endpoint URLs, used only for routing system compatibility with HTTP-based trustless gateways - no libp2p cryptographic operations are performed with these IDs

Changed

  • Modernized Docker build configuration (#118)
  • Updated to Go 1.24/1.25 (#115, #118)

[v0.9.1]

Added

  • Added exporting of routing http client metrics: the endpoint will now include someguy_routing_http_client_* metrics when delegated routing clients are used:
    • Histogram: the latency of operations by the routing HTTP client
      • someguy_routing_http_client_latency_bucket{code,error,host,operation,le}
      • someguy_routing_http_client_latency_sum{code,error,host,operation}
      • someguy_routing_http_client_latency_count{code,error,host,operation}
    • Histogram: the number of elements in a response collection
      • someguy_routing_http_client_length_bucket{host,operation,le}
      • someguy_routing_http_client_length_sum{host,operation}
      • someguy_routing_http_client_length_count{host,operation}
    • See docs/metrics.md for more details.

[v0.9.0]

Added

  • Added http-block-provider-endpoints and http-block-provider-peerids options to enable using a trustless HTTP gateway as a source for synthetic content routing records.
    • When the configured gateway responds with HTTP 200 to an HTTP HEAD request for a block (HEAD /ipfs/{cid}?format=raw), FindProviders returns a provider record containing a predefined PeerID and the HTTP gateway as a multiaddr with /tls/http suffix.

Changed

Removed

Fixed

Security

[v0.8.1]

This release includes a number of dependency updates that include bug fixes and improvements.

Changed

[v0.8.0]

Added

  • Enabled CORS for PUT requests to /routing/v1/ipns.

[v0.7.1]

Fixed

  • Fix a bug whereby, cached peers with private multiaddrs were returned in /routing/v1/providers responses, as they were not passing through sanitizeRouter.

[v0.7.0]

Added

  • Peer addresses are cached for 48h to match provider record expiration on Amino DHT.
  • In the background, someguy probes cached peers at most once per hour (PeerProbeThreshold) by attempting to dial them to keep their multiaddrs up to date. If a peer is not reachable, an exponential backoff is applied to reduce the frequency of probing. If a cached peer is unreachable for more than 48h (MaxBackoffDuration), it is removed from the cache.
  • Someguy now augments providers missing addresses in FindProviders with cached addresses. If a peer is encountered with no cached addresses, FindPeer is dispatched in the background and the result is streamed in the reponse. Providers for which no addresses can be found, are omitted from the response.
    • This can be enabled via SOMEGUY_CACHED_ADDR_BOOK=true|false (enabled by default)
    • Two additional configuration options for the cachedAddrBook implementation:
      • SOMEGUY_CACHED_ADDR_BOOK_ACTIVE_PROBING whether to actively probe cached peers in the background to keep their multiaddrs up to date.
      • SOMEGUY_CACHED_ADDR_BOOK_RECENT_TTL to adjust the TTL for cached addresses of recently connected peers.

[v0.6.0]

Added

  • Add request tracing with sampling or require token for requests with Traceparent header. See tracing.md for more details.

Changed

  • go-libp2p-kad-dht updated to v0.28.1
  • Metrics someguy_http_request_duration_seconds and someguy_http_response_size_bytes were replaced with delegated_routing_server_http_request_duration_seconds and delegated_routing_server_http_response_size_bytes from upstream boxo/routing/http/server.

[v0.5.3]

Fixed

  • default config: restore proxying of all results from IPNI at cid.contact #83

[v0.5.2]

Changed

[v0.5.0]

Added

  • Added support for IPIP-484 which allows filtering network transports (addresses) and transfer protocols (bitswap, etc) in /routing/v1/ responses. #82

Changed

[v0.4.2]

Fixed

  • go-libp2p-kad-dht v0.26.1 fixes a bug where FindPeer did not return results for peers behind NAT which only have p2p-circuit multiaddrs. #80

[v0.4.1]

Added

  • SOMEGUY_LIBP2P_LISTEN_ADDRS config environment variable for customizing the interfaces, ports, and transports of the libp2p host created by someguy. #79

Fixed

  • enabled NAT port map and Hole Punching to increase connectivity in non-public network topologies #79

[v0.4.0]

Changed

Fixed

[v0.3.0]

Changed

Fixed

  • --version now includes the release tag
  • start command supports a graceful shutdown and improved handling of interrupt signals

[v0.2.3]

Changed

  • The resource manager's defaults have been improved based on Rainbow's and Kubo's defaults. In addition, you can now customize a few options using flags, or environment variables.

[v0.2.2]

Fixed

  • The /routing/v1/peers endpoint correctly filters out private addresses.

[v0.2.1]

Fixed

  • Upgraded Boxo with fix to ensure that /routing/v1/peers endpoint accepts all variants of Peer IDs that are seen in the wild.