Composable and future-proof network addresses
Multiaddr aims to make network addresses future-proof, composable, and efficient.
Current addressing schemes have a number of problems.
Multiaddr solves these problems by modelling network addresses as arbitrary encapsulations of protocols.
Multiaddr was originally thought up by @jbenet.
Multiaddrs are parsed from left to right, but they should be interpreted right to left. Each component of a multiaddr wraps all the left components in its context. For example, the multiaddr /dns4/example.com/tcp/1234/tls/ws/tls
(ignore the double encryption for now) is interpreted by taking the first tls
component from the right and interpreting it as the libp2p security protocol to use for the connection, then passing the rest of the multiaddr to the websocket transport to create the websocket connection. The websocket transport sees /dns4/example.com/tcp/1234/tls/ws/
and interprets the tls
in this context to mean that this is going to be a secure websocket connection. The websocket transport also gets the host to dial along with the tcp port from the rest of the multiaddr.
Components to the right can also provide parameters to components to the left, since they are in charge of the rest of the multiaddr's interpretation. For example, in /ip4/1.2.3.4/tcp/1234/tls/p2p/QmFoo
the p2p
component has the value of the peer id and it passes it to the next component, in this case the tls
security protocol, as the expected peer id for this connection. Another example is /ip4/.../p2p/QmR/p2p-circuit/p2p/QmA
, here p2p/QmA
is passed to p2p-circuit
and then the p2p-circuit
component knows it needs to use the rest of the multiaddr as the information to connect to the relay node.
This enables nesting and arbitrary parameters. A component can parse arbitrary data with some encoding and pass it as a parameter to the next component of the multiaddr. For example, we could reference a specific HTTP path by composing path
and urlencode
components along with an http
component. This would look like /dns4/example.com/http/GET/path/percentencode/somepath%2ftosomething
. The percentencode
parses the data and passes it as a parameter to path
, which passes it as a named parameter (path=somepath/tosomething
) to a GET
request. A user may not like percentencode for their use case and may prefer to use lenprefixencode
to have the multiaddr instead look like /dns4/example.com/http/GET/path/lenprefixencode/20_somepath/tosomething
. This would work the same and require no changes to the path
or GET
component. It's important to note that the binary representation of the data in percentencode
and lenprefixencode
would be the same. The only difference is how it appears in the human-readable representation.
TODO: unpack the shortcomings of URLs
TODO: case study: domain fronting
TODO: case study: tunnelling
TODO: case study: http proxying
TODO: case study: multi-hop circuit relay
TODO: case study: protocol migrations (e.g. ip4/ip6, 4in6, 6in4)
Although multiaddrs are self-describing, it's possible to further encapsulate them based on context. For example in a web browser, it's obvious that, given a hostname, HTTP should be spoken. The specifics of this HTTP connection are not important (except maybe the use of TLS), and will be derived from the browser's capabilities and configuration.
The resulting layers of encapsulation reflect exactly how the bidirectional stream between client and server is constructed.
Now you can imagine how based on the browser's configuration, the multiaddr might look different. For example you could use HTTP proxying or SOCKS proxying, or use domain fronting to evade censorship. This kind of proxying is of course possible without multiaddr, but only with multiaddr do we have a way of consistently addressing these networking constructions.
(/<protoName string>/<value string>)+
/ip4/127.0.0.1/udp/1234
(<protoCode uvarint><value []byte>)+
0x4 0x7f 0x0 0x0 0x1 0x91 0x2 0x4 0xd2
Multiaddr and all other multiformats use unsigned varints (uvarint). Read more about it in multiformats/unsigned-varint.
TODO: specify the encoding (byte-array to string) procedure
TODO: specify the decoding (string to byte-array) procedure
See protocols.csv for a list of protocol codes and names, and protocols/ for specifications of the currently supported protocols.
TODO: most of these are way underspecified
multiaddr
sub-module of Python module multiformats - alphamultiaddr
part of Kotlin project multiformat - alphaTODO: reconsider these alpha/beta/stable labels
Contributions welcome. Please check out the issues.
Check out our contributing document for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS Code of Conduct.
Small note: If editing the README, please conform to the standard-readme specification.
This repository is only for documents. All of these are licensed under the CC-BY-SA 3.0 license, © 2016 Protocol Labs Inc. Any code is under a MIT © 2016 Protocol Labs Inc.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4