Releases: ipfs/kubo
Release v0.6.0
This is a relatively small release in terms of code changes, but it contains some significant changes to the IPFS protocol.
Highlights
The highlights in this release include:
- The QUIC transport is enabled by default. Furthermore, go-ipfs will automatically run a migration to listen on the QUIC transport (on the same address/port as the TCP transport) to make this upgrade process seamless.
- The new NOISE security transport is now supported but won't be selected by default. This transport will replace SECIO as the default cross-language interoperability security transport. TLS 1.3 will still remain the default security transport between go-ipfs nodes for now.
MIGRATION: This release contains a small config migration to enable listening on the QUIC transport in addition the TCP transport. This migration will:
- Normalize multiaddrs in the bootstrap list to use the
/p2p/Qm...
syntax for multiaddrs instead of the/ipfs/Qm...
syntax. - Add QUIC addresses for the default bootstrapers, as necessary. If you've removed the default bootstrappers from your bootstrap config, the migration won't add them back.
- Add a QUIC listener address to mirror any TCP addresses present in your config. For example, if you're listening on
/ip4/0.0.0.0/tcp/1234
, this migration will add a listen address for/ip4/0.0.0.0/udp/1234/quic
.
QUIC by default
This release enables the QUIC transport (draft 28) by default for both inbound and outbound connections. When connecting to new peers, libp2p will continue to dial all advertised addresses (tcp + quic) in parallel so if the QUIC connection fails for some reason, the connection should still succeed.
The QUIC transport has several key benefits over the current TCP based transports:
- It takes fewer round-trips to establish a connection. With the QUIC transport, the IPFS handshake takes two round trips (one to establish the QUIC connection, one for the libp2p handshake). In the future, we should be able to reduce this to one round trip for the initial connection, and zero round trips for subsequent connections to a previously seen peer. This is especially important for DHT requests that contact many new peers.
- Because it's UDP based instead of TCP based, it uses fewer file descriptors. The QUIC transport will open one UDP socket per listen address instead of one socket per connection. This should, in the future, allow us to keep more connections open.
- Because QUIC connections don't consume file descriptors, we're able to remove the rate limit on outbound QUIC connections, further speeding up DHT queries.
Unfortunately, this change isn't without drawbacks: the QUIC transport may not be able to max out some links (usually due to poorly tuned kernel parameters). On the other hand, it may also be faster in some cases
If you hit this performance issue on Linux, you should tune the net.core.rmem_default
and net.core.rmem_max
sysctl parameters to increase your UDP receive buffer sizes.
If necessary, you can disable the QUIC transport by running:
> ipfs config --json Swarm.Transports.Network.QUIC false
NOTE: The QUIC transport included in this release is backwards incompatible with the experimental QUIC transport included in previous releases. Unfortunately, the QUIC protocol underwent some significant breaking changes and supporting multiple versions wasn't an option. In practice this degrades gracefully as go-ipfs will simply fall back on the TCP transport when dialing nodes with incompatible QUIC versions.
Noise Transport
This go-ipfs release introduces a new security transport: libp2p Noise (built from the Noise Protocol Framework). While TLS1.3 remains the default go-ipfs security transport, Noise is simpler to implement from scratch and will be the standard cross-platform libp2p security transport going forward.
This brings us one step closer to deprecating and removing support for SECIO.
While enabled by default, Noise won't actually be used by default it's negotiated. Given that TLS1.3 is still the default security transport for go-ipfs, this usually won't happen. If you'd like to prefer Noise over other security transports, you can change its priority in the config (Swarm.Transports.Security.Noise
).
Gateway
This release brings two gateway-relevant features: custom 404 pages and base36 support.
Custom 404
You can now customize 404 Not Found
error pages by including an ipfs-404.html
file somewhere in the request path. When a requested file isn't found, go-ipfs will look for an ipfs-404.html
in the same directory as the requested file, and in each ancestor directory. If found, this file will be returned (with a 404 status code) instead of the usual error message.
Support for Base36
This release adds support for a new multibase encoding: base36. Base36 is an optimally efficient case-insensitive alphanumeric encoding. Case-insensitive alphanumeric encodings are important for the subdomain gateway as domain names are case insensitive.
While base32 (the current default encoding used in subdomains) is simpler than base36, it's not optimally efficient and base36 Ed25519 IPNS keys are 2 characters too big to fit into the 63 character subdomain length limit. The extra efficiency from base36 brings us under this limit and allows Ed25519 IPNS keys to work with the subdomain gateway.
This release adds support for base36 but won't use it by default. If you'd like to re-encode an Ed25519 IPNS key into base36, you can use the ipfs cid format
command:
$ ipfs cid format -v 1 --codec libp2p-key -b base36 bafzaajaiaejca4syrpdu6gdx4wsdnokxkprgzxf4wrstuc34gxw5k5jrag2so5gk k51qzi5uqu5dj16qyiq0tajolkojyl9qdkr254920wxv7ghtuwcz593tp69z9m
Gossipsub Upgrade
This release brings a new gossipsub protocol version: 1.1. You can read about it in the blog post.
Connectivity
This release introduces a new "peering" feature. The peering subsystem configures go-ipfs to connect to, remain connected to, and reconnect to a set of nodes. Nodes should use this subsystem to create "sticky" links between frequently useful peers to improve reliability.
Use-cases:
- An IPFS gateway connected to an IPFS cluster should peer to ensure that the gateway can always fetch content from the cluster.
- A dapp may peer embedded go-ipfs nodes with a set of pinning services or textile cafes/hubs.
- A set of friends may peer to ensure that they can always fetch each other's content.
Changelog
- github.com/ipfs/go-ipfs:
- fix 3 bugs responsible for a goroutine leak (plus one other bug) (ipfs/go-ipfs#7491)
- docs(config): update toc (ipfs/go-ipfs#7483)
- feat: transport config (ipfs/go-ipfs#7479)
- fix the minimal go version under 'Build from Source' (ipfs/go-ipfs#7459)
- fix(migration): migrate /ipfs/ bootstrappers to /p2p/
- fix(migration): correctly migrate quic addresses
- chore: add migration to listen on QUIC by default
- backport fixes (ipfs/go-ipfs#7405)
- Use bitswap sessions for
ipfs refs
. - Update to webui 2.9.0
- Use bitswap sessions for
- feat: add noise support (ipfs/go-ipfs#7365)
- feat: implement peering service (ipfs/go-ipfs#7362)
- Include the git blob id of the dir-index bundle in the ETag (ipfs/go-ipfs#7360)
- feat: bootstrap in dht when the routing table is empty (ipfs/go-ipfs#7340)
- quic: remove experimental status and add it to the default config (ipfs/go-ipfs#7349)
- fix: support directory listings even if a 404 page is present (ipfs/go-ipfs#7339)
- doc(plugin): document plugin config (ipfs/go-ipfs#7309)
- test(sharness): fix fuse tests (ipfs/go-ipfs#7320)
- docs: update experimental-features doc with IPNS over pubsub changes. (ipfs/go-ipfs#7334)
- docs: cleanup config formatting (ipfs/go-ipfs#7336)
- fix(gateway): ensure directory listings have Content-Type text/html (ipfs/go-ipfs#7330)
- test(sharness): test the local symlink (ipfs/go-ipfs#7332)
- misc config/experimental-features doc fixes (ipfs/go-ipfs#7333)
- fix: correctly trim resolved IPNS addresses (ipfs/go-ipfs#7331)
- Gateway renders pretty 404 pages if available (ipfs/go-ipfs#4233)
- feat: add a dht stat command (ipfs/go-ipfs#7221)
- fix: update dists url for OpenBSD support (ipfs/go-ipfs#7311)
- docs: X-Forwarded-Proto: https (ipfs/go-ipfs#7306)
- fix(mkreleaselog): make robust against running in different working directories (ipfs/go-ipfs#7310)
- fix(mkreleasenotes): include commits directly to master (ipfs/go-ipfs#7296)
- write a...
Release v0.6.0-rc7
Tracking issue: #7347
Release v0.6.0-rc6
Tracking issue: #7347
Release v0.6.0-rc1
Tracking issue: #7366.
Release v0.5.1
Hot on the heels of 0.5.0 is 0.5.1 with some important but small bug fixes. This release:
- Removes the 1 minute timeout for IPNS publishes (fixes #7244).
- Backport a DHT fix to reduce CPU usage for canceled requests.
- Fixes some timer leaks in the QUIC transport (lucas-clemente/quic-go#2515).
Changelog
- github.com/ipfs/go-ipfs:
- IPNS timeout patch from master (ipfs/go-ipfs#7276)
- github.com/libp2p/go-libp2p-core (v0.5.2 -> v0.5.3):
- feat: add a function to tell if a context subscribes to query events (libp2p/go-libp2p-core#147)
- github.com/libp2p/go-libp2p-kad-dht (v0.7.10 -> v0.7.11):
- fix: optimize for the case where we're not subscribing to query events (libp2p/go-libp2p-kad-dht#624)
- fix: don't spin when the event channel is closed (libp2p/go-libp2p-kad-dht#622)
- github.com/libp2p/go-libp2p-routing-helpers (v0.2.2 -> v0.2.3):
- fix: avoid subscribing to query events unless necessary (libp2p/go-libp2p-routing-helpers#43)
- github.com/lucas-clemente/quic-go (v0.15.5 -> v0.15.7):
- reset the PTO when dropping a packet number space
- move deadlineTimer declaration out of the Read loop
- stop the deadline timer in Stream.Read and Write
- fix buffer use after it was released when sending an INVALID_TOKEN error
- create the session timer at the beginning of the run loop
- stop the timer when the session's run loop returns
Contributors
Contributor | Commits | Lines ± | Files Changed |
---|---|---|---|
Marten Seemann | 10 | +81/-62 | 19 |
Steven Allen | 5 | +42/-18 | 10 |
Adin Schmahmann | 1 | +2/-8 | 1 |
dependabot | 2 | +6/-2 | 4 |
v0.5.0
We're excited to announce go-ipfs 0.5.0! This is by far the largest go-ipfs release with ~2500 commits, 98 contributors, and over 650 PRs across ipfs, libp2p, and multiformats.
Highlights
Content Routing
The primary focus of this release was on improving content routing. That is, advertising and finding content. To that end, this release heavily focuses on improving the DHT.
Improved DHT
The distributed hash table (DHT) is how IPFS nodes keep track of who has what data. The DHT implementation has been almost completely rewritten in this release. Providing, finding content, and resolving IPNS records are now all much faster. However, there are risks involved with this update due to the significant amount of changes that have gone into this feature.
The current DHT suffers from three core issues addressed in this release:
- Most peers in the DHT cannot be dialed (e.g., due to firewalls and NATs). Much of a DHT query time is wasted trying to connect to peers that cannot be reached.
- The DHT query logic doesn't properly terminate when it hits the end of the query and, instead, aggressively keeps on searching.
- The routing tables are poorly maintained. This can cause search performance to slow down linearly with network size, instead of logarithmically as expected.
Reachability
We have addressed the problem of undialable nodes by having nodes wait to join the DHT as server nodes until they've confirmed that they are reachable from the public internet.
To ensure that nodes which are not publicly reachable (ex behind VPNs, offline LANs, etc.) can still coordinate and share data, go-ipfs 0.5 will run two DHTs: one for private networks and one for the public internet. Every node will participate in a LAN DHT and a public WAN DHT. See Dual DHT for more details.
Dual DHT
All IPFS nodes will now run two DHTs: one for the public internet WAN, and one for their local network LAN.
- When connected to the public internet, IPFS will use both DHTs for finding peers, content, and IPNS records. Nodes only publish provider and IPNS records to the WAN DHT to avoid flooding the local network.
- When not connected to the public internet, nodes publish provider and IPNS records to the LAN DHT.
The WAN DHT includes all peers with at least one public IP address. This release will only consider an IPv6 address public if it is in the public internet range 2000::/3
.
This feature should not have any noticeable impact on go-ipfs, performance, or otherwise. Everything should continue to work in all the currently supported network configurations: VPNs, disconnected LANs, public internet, etc.
Query Logic
We've improved the DHT query logic to more closely follow Kademlia. This should significantly speed up:
- Publishing IPNS & provider records.
- Resolving IPNS addresses.
Previously, nodes would continue searching until they timed out or ran out of peers before stopping (putting or returning data found). Now, nodes will now stop as soon as they find the closest peers.
Routing Tables
Finally, we've addressed the poorly maintained routing tables by:
- Reducing the likelihood that the connection manager will kill connections to peers in the routing table.
- Keeping peers in the routing table, even if we get disconnected from them.
- Actively and frequently querying the DHT to keep our routing table full.
- Prioritizing useful peers that respond to queries quickly.
Testing
The DHT rewrite was made possible by Testground, our new testing framework. Testground allows us to spin up multi-thousand node tests with simulated real-world network conditions. By combining Testground and some custom analysis tools, we were able to gain confidence that the new DHT implementation behaves correctly.
Provider Record Changes
When you add content to your IPFS node, you advertise this content to the network by announcing it in the DHT. We call this providing.
However, go-ipfs has multiple ways to address the same underlying bytes. Specifically, we address content by content ID (CID) and the same underlying bytes can be addressed using (a) two different versions of CIDs (CIDv0 and CIDv1) and (b) with different codecs depending on how we're interpreting the data.
Prior to go-ipfs 0.5.0, we used the content id (CID) in the DHT when sending out provider records for content. Unfortunately, this meant that users trying to find data announced using one CID wouldn't find nodes providing the content under a different CID.
In go-ipfs 0.5.0, we're announcing data by multihash, not CID. This way, regardless of the CID version used by the peer adding the content, the peer trying to download the content should still be able to find it.
Warning: as part of the network, this could impact finding content added with CIDv1. Because go-ipfs 0.5.0 will announce and search for content using the bare multihash (equivalent to the v0 CID), go-ipfs 0.5.0 will be unable to find CIDv1 content published by nodes prior to go-ipfs 0.5.0 and vice-versa. As CIDv1 is not enabled by default so we believe this will have minimal impact. However, users are strongly encouraged to upgrade as soon as possible.
Content Transfer
A secondary focus in this release was improving content transfer, our data exchange protocols.
Refactored Bitswap
This release includes a major Bitswap refactor, running a new and backward compatible Bitswap protocol. We expect these changes to improve performance significantly.
With the refactored Bitswap, we expect:
- Few to no duplicate blocks when fetching data from other nodes speaking the new protocol.
- Better parallelism when fetching from multiple peers.
The new Bitswap won't magically make downloading content any faster until both seeds and leaches have updated. If you're one of the first to upgrade to 0.5.0
and try downloading from peers that haven't upgraded, you're unlikely to see much of a performance improvement.
Server-Side Graphsync Support (Experimental)
Graphsync is a new exchange protocol that operates at the IPLD Graph layer instead of the Block layer like bitswap.
For example, to download "/ipfs/QmExample/index.html":
- Bitswap would download QmFoo, lookup "index.html" in the directory named by
QmFoo, resolving it to a CID QmIndex. Finally, bitswap would download QmIndex. - Graphsync would ask peers for "/ipfs/QmFoo/index.html". Specifically, it would ask for the child named "index.html" of the object named by "QmFoo".
This saves us round-trips in exchange for some extra protocol complexity. Moreover, this protocol allows specifying more powerful queries like "give me everything under QmFoo". This can be used to quickly download a large amount of data with few round-trips.
At the moment, go-ipfs cannot use this protocol to download content from other peers. However, if enabled, go-ipfs can serve content to other peers over this protocol. This may be useful for pinning services that wish to quickly replicate client data.
To enable, run:
> ipfs config --json Experimental.GraphsyncEnabled true
Datastores
Continuing with the of improving our core data handling subsystems, both of the datastores used in go-ipfs, Badger and flatfs, have received important updates in this release:
Badger
Badger has been in go-ipfs for over a year as an experimental feature, and we're promoting it to stable (but not default). For this release, we've switched from writing to disk synchronously to explicitly syncing where appropriate, significantly increasing write throughput.
The current and default datastore used by go-ipfs is FlatFS. FlatFS essentially stores blocks of data as individual files on your file system. However, there are lots of optimizations a specialized database can do that a standard file system can not.
The benefit of Badger is that adding/fetching data to/from Badger is significantly faster than adding/fetching data to/from the default datastore, FlatFS. In some tests, adding data to Badger is 32x faster than FlatFS (in this release).
Enable Badger
In this release, we're marking the badger datastore as stable. However, we're not yet enabling it by default. You can enable it at initialization by running: ipfs init --profile=badgerds
Issues with Badger
While Badger is a great solution, there are some issues you should consider before enabling it.
Badger is complicated. FlatFS pushes all the complexity down into the filesystem itself. That means that FlatFS is only likely to lose your data if your underlying filesystem gets corrupted while there are more opportunities for Badger itself to get corrupted.
Badger can use a lot of memory. In this release, we've tuned Badger to use ~20MB
of memory by default. However, it can still produce spikes as large as 1GiB
of data in memory usage when garbage collecting.
Finally, Badger isn't very aggressive when it comes to garbage collection, and we're still investigating ways to get it to more aggressively clean up after itself.
We suggest you use Badger if:
- Performance is your main requirement.
- You rarely delete anything.
- You have some memory to spare.
Flatfs
In the flatfs datastore, we've fixed an issue where temporary files could be left behind in some cases. While this release will avoid leaving behind temporary files, you may want to remove any left behind by previous releases:
> rm ~/.ipfs/blocks/*...
v0.5.0-rc4
Since RC3:
- Reduce duplicate blocks in bitswap by increasing some timeouts and fixing the use of sessions in the
ipfs pin
command. - Fix some bugs in the
ipfs dht
CLI commands. - Ensure bitswap cancels are sent when the request is aborted.
- Optimize some bitswap hot-spots and reduce allocations.
- Harden use of the libp2p identify protocol to ensure we never "forget" our peer's protocols. This is important in this release because we're using this information to determine whether or not a peer is a member of the DHT.
- Fix some edge cases where we might not notice that a peer has transitioned to/from a DHT server/client.
- Avoid forgetting our observed external addresses when no new connections have formed in the last 10 minutes. This has been a mild issue since 2016 but was exacerbated by this release as we now push address updates to our peers when our addresses change. Unfortunately, combined, this meant we'd tell our peers to forget our external addresses (but only if we haven't formed a single new connection in the last 10 minutes).
Release v0.5.0-rc3
Since RC2:
- Many typo fixes.
- Merged some improvements to the gateway directory listing template.
- Performance tweaks in bitswap and the DHT.
- More integration tests for the DHT.
- Fixed redirects to the subdomain gateway for directory listings.
- Merged some debugging code for QUIC.
- Update the WebUI to pull in some bug fixes.
- Update flatfs to fix some issues on windows in the presence of AVs.
- Updated go version to 1.13.10.
- Avoid adding IPv6 peers to the WAN DHT if their only "public" IP addresses aren't in the public internet IPv6 range.
Release v0.5.0-rc2
Release issue: #7109
Changes between RC1 and RC2
Other than bug fixes, the following major changes were made between RC1 and RC2.
QUIC Upgrade
In RC1, we downgraded to a previous version of the (experimental) QUIC transport so we could build on go 1.13. In RC2, our QUIC transport was patched to support go 1.13 so we've upgraded back to the latest version.
NOTE: The latest version implements a different and incompatible draft (draft 27) of the QUIC protocol than the previous RC and go-ipfs 0.4.23. In practice, this shouldn't cause any issues as long as your node supports transports other than QUIC (also necessary to communicate with the vast majority of the network).
DHT "auto" mode
In this RC, the DHT will not enter "server" mode until your node determines that it is reachable from the public internet. This prevents unreachable nodes from polluting the DHT. Please read the "New DHT" section in the issue body for more info.
AutoNAT
IPFS has a protocol called AutoNAT for detecting whether or not a node is "reachable" from the public internet. In short:
- An AutoNAT client asks a node running an AutoNAT service if it can be reached at one of a set of guessed addresses.
- The AutoNAT service will attempt to "dialback" those addresses (with some restrictions, e.g., we won't dial back to a different IP address).
- If the AutoNAT service succeeds, it will report back the address it successfully dialed and the AutoNAT client will now know that it is reachable from the public internet.
In go-ipfs 0.5, all nodes act as AutoNAT clients to determine if they should switch into DHT server mode.
As of this RC, all nodes (except new nodes initialized with the "lowpower" config profile) will also run a rate-limited AutoNAT service by default. This should have minimal overhead but we may change the defaults in RC3 (e.g., rate limit further or only enable the AutoNAT service on DHT servers).
In addition to enabling the AutoNAT service by default, this RC changes the AutoNAT config options around:
- It removes the
Swarm.EnableAutoNATService
option. - It Adds an
AutoNAT
config section (empty by default). This new section is documented in docs/config.md along with the rest of the config file.
LAN/WAN DHT
As forwarned in the RC1 release notes, RC2 includes the split LAN/WAN DHT. All IPFS nodes will now run two DHTs: one for the public internet (WAN) and one for their local network (LAN).
- When connected to the public internet, IPFS will use both DHTs for finding peers, content, and IPNS records, but will only publish records (provider and IPNS) to the WAN DHT to avoid flooding the local network.
- When not connected to the public internet, IPFS will publish provider and IPNS records to the LAN DHT.
This feature should not have any noticeable (performance or otherwise) impact and go-ipfs should continue to work in all the currently supported network configurations: VPNs, disconnected LANs, public internet, etc.
In a future release, we hope to use this feature to limit the advertisement of private addresses to the local LAN.
Release v0.5.0-rc1
This is the first RC for go-ipfs 0.5.0. See #7109 for details.