multiformats/js-multiaddr

Encapsulation/decapsulation semantics are backwards

Closed this issue · 1 comments

The docs say:

addr.encapsulate(str)
Returns a new multiaddress that encapsulates addr in a new protocol string, str.

addr.encapsulate('/sctp/5678')
// <Multiaddr /ip4/127.0.0.1/udp/1234/sctp/5678>

I am fairly sure this is intended to illustrate RFC6951 encapsulation. However, the RFC clearly states that STCP is "encapsulated into" UDP (passive) or, more plainly, UDP encapsulates STCP. So, in this case the docs can be corrected to something like "Returns a new multiaddress that encapsulates a new protocol in the stack already specified by addr"

However, the semantics of decapsulate are wrong at the API level:

addr.decapsulate(str)
Returns a new multiaddress with the right-most protocol string str removed.

multiaddress('/ip4/127.0.0.1/udp/1234').decapsulate('/udp')
// <Multiaddr /ip4/127.0.0.1>

Let's extend this to a fuller example:

<Multiaddr 043692e377062329a5032212204ca777e3b2d5d6dc5524ddb742b3b3fd3ce19e8ef11e3e6172dcc42f73638859 - /ip4/54.146.227.119/tcp/9001/ipfs/QmTVsocFCSEdPyM8dZ734GRhjvvmYyL9fShyezVkbPj17E>
> m.decapsulate('/ip4')
<Multiaddr  - />
> m.decapsulate('/tcp')
<Multiaddr 043692e377 - /ip4/54.146.227.119>
> m.decapsulate('/ipfs')
<Multiaddr 043692e377062329 - /ip4/54.146.227.119/tcp/9001>

There's two problems with this.

One: the API should specify either the outer layer which to strip (as in https://loicpefferkorn.net/ipdecap/) or the inner layer which to return https://tools.ietf.org/html/rfc3948#section-3.3

Two: there appears to be no way to actually get the innermost protocol using these calls -- please correct me if I'm wrong

Both of these issues can be corrected by returning a tuple of [outer, inner] multiaddresses from the decapsulate call.

The current behavior can also be preserved as a getEncapsulatingProtocol method.

Upon further inspection, it seems like the undocumented method stringTuples does allow me to extract the desired layer without totally manual parsing