Skip to content

Commit

Permalink
feat: add unix protocol support and update protocol table (#84)
Browse files Browse the repository at this point in the history
* feat: update protocol table to match latest

* feat: add unix protocol and path support

* chore: fix lint
  • Loading branch information
jacobheun authored Feb 25, 2019
1 parent ebd35c3 commit d4d3d9b
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 12 deletions.
14 changes: 13 additions & 1 deletion src/codec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ function stringToStringTuples (str) {
throw ParseError('invalid address: ' + str)
}

// if it's a path proto, take the rest
if (proto.path) {
tuples.push([
part,
// TODO: should we need to check each path part to see if it's a proto?
// This would allow for other protocols to be added after a unix path,
// however it would have issues if the path had a protocol name in the path
cleanPath(parts.slice(p).join('/'))
])
break
}

tuples.push([part, parts[p]])
}

Expand All @@ -69,7 +81,7 @@ function stringTuplesToString (tuples) {
}
})

return '/' + parts.join('/')
return cleanPath(parts.join('/'))
}

// [[str name, str addr]... ] -> [[int code, Buffer]... ]
Expand Down
4 changes: 4 additions & 0 deletions src/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ Convert.toString = function convertToString (proto, buf) {
case 132: // sctp
return buf2port(buf)

case 53: // dns
case 54: // dns4
case 55: // dns6
case 56: // dnsaddr
case 400: // unix
return buf2str(buf)

case 421: // ipfs
Expand All @@ -56,9 +58,11 @@ Convert.toBuffer = function convertToBuffer (proto, str) {
case 132: // sctp
return port2buf(parseInt(str, 10))

case 53: // dns
case 54: // dns4
case 55: // dns6
case 56: // dnsaddr
case 400: // unix
return str2buf(str)

case 421: // ipfs
Expand Down
27 changes: 27 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,33 @@ Multiaddr.prototype.getPeerId = function getPeerId () {
return b58str
}

/**
* Extract the path if the multiaddr contains one
*
* @return {String|null} path - The path of the multiaddr, or null if no path protocol is present
* @example
* const mh1 = Multiaddr('/ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock')
* // <Multiaddr 0408080808060438 - /ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock>
*
* // should return utf8 string or null if the id is missing or invalid
* const path = mh1.getPath()
*/
Multiaddr.prototype.getPath = function getPath () {
let path = null
try {
path = this.stringTuples().filter((tuple) => {
const proto = protocols(tuple[0])
if (proto.path) {
return true
}
})[0][1]
} catch (e) {
path = null
}

return path
}

/**
* Checks if two Multiaddrs are the same
*
Expand Down
29 changes: 18 additions & 11 deletions src/protocols-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,38 @@ Protocols.V = V
Protocols.table = [
[4, 32, 'ip4'],
[6, 16, 'tcp'],
[273, 16, 'udp'],
[33, 16, 'dccp'],
[41, 128, 'ip6'],
[42, V, 'ip6zone'],
[53, V, 'dns', 'resolvable'],
[54, V, 'dns4', 'resolvable'],
[55, V, 'dns6', 'resolvable'],
[56, V, 'dnsaddr', 'resolvable'],
[132, 16, 'sctp'],
// all of the below use varint for size
[273, 16, 'udp'],
[275, 0, 'p2p-webrtc-star'],
[276, 0, 'p2p-webrtc-direct'],
[277, 0, 'p2p-stardust'],
[290, 0, 'p2p-circuit'],
[301, 0, 'udt'],
[302, 0, 'utp'],
[400, V, 'unix', false, 'path'],
// `p2p` is the preferred name for 421
[421, Protocols.lengthPrefixedVarSize, 'p2p'],
[421, V, 'p2p'],
// `ipfs` has been added after `p2p` so that it is used by default.
// The reason for this is to provide better backwards support for
// code bases that do not yet support the `p2p` proto name. Eventually
// `p2p` should become the default.
[421, Protocols.lengthPrefixedVarSize, 'ipfs'],
[480, 0, 'http'],
[421, V, 'ipfs'],
[443, 0, 'https'],
[444, 96, 'onion'],
[445, 296, 'onion3'],
[446, V, 'garlic64'],
[460, 0, 'quic'],
[477, 0, 'ws'],
[478, 0, 'wss'],
[479, 0, 'p2p-websocket-star'],
[277, 0, 'p2p-stardust'],
[275, 0, 'p2p-webrtc-star'],
[276, 0, 'p2p-webrtc-direct'],
[290, 0, 'p2p-circuit']
[480, 0, 'http']
]

Protocols.names = {}
Expand All @@ -65,12 +71,13 @@ Protocols.table.map(row => {

Protocols.object = p

function p (code, size, name, resolvable) {
function p (code, size, name, resolvable, path) {
return {
code: code,
size: size,
name: name,
resolvable: Boolean(resolvable)
resolvable: Boolean(resolvable),
path: Boolean(path)
}
}

Expand Down
79 changes: 79 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,27 @@ describe('variants', () => {
expect(addr.toString()).to.equal(str)
})

it('ip4 + tcp + unix', () => {
const str = '/ip4/127.0.0.1/tcp/80/unix/a/b/c/d/e/f'
const addr = multiaddr(str)
expect(addr).to.have.property('buffer')
expect(addr.toString()).to.equal(str)
})

it('ip6 + tcp + http', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/http'
const addr = multiaddr(str)
expect(addr).to.have.property('buffer')
expect(addr.toString()).to.equal(str)
})

it('ip6 + tcp + unix', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/unix/a/b/c/d/e/f'
const addr = multiaddr(str)
expect(addr).to.have.property('buffer')
expect(addr.toString()).to.equal(str)
})

it('ip4 + tcp + https', () => {
const str = '/ip4/127.0.0.1/tcp/8000/https'
const addr = multiaddr(str)
Expand Down Expand Up @@ -323,6 +337,13 @@ describe('variants', () => {
expect(addr.toString()).to.equal(str.replace('/p2p/', '/ipfs/'))
})

it('unix', () => {
const str = '/unix/a/b/c/d/e'
const addr = multiaddr(str)
expect(addr).to.have.property('buffer')
expect(addr.toString()).to.equal(str)
})

it('p2p', () => {
const str = '/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
const addr = multiaddr(str)
Expand Down Expand Up @@ -413,11 +434,13 @@ describe('helpers', () => {
.to.eql([{
code: 4,
name: 'ip4',
path: false,
size: 32,
resolvable: false
}, {
code: 302,
name: 'utp',
path: false,
size: 0,
resolvable: false
}])
Expand All @@ -429,16 +452,19 @@ describe('helpers', () => {
).to.be.eql([{
code: 4,
name: 'ip4',
path: false,
size: 32,
resolvable: false
}, {
code: 302,
name: 'utp',
path: false,
size: 0,
resolvable: false
}, {
code: 421,
name: 'ipfs',
path: false,
size: -1,
resolvable: false
}])
Expand All @@ -450,16 +476,43 @@ describe('helpers', () => {
).to.be.eql([{
code: 4,
name: 'ip4',
path: false,
size: 32,
resolvable: false
}, {
code: 302,
name: 'utp',
path: false,
size: 0,
resolvable: false
}, {
code: 421,
name: 'ipfs',
path: false,
size: -1,
resolvable: false
}])
})

it('works with unix', () => {
expect(
multiaddr('/ip4/0.0.0.0/tcp/8000/unix/tmp/p2p.sock').protos()
).to.be.eql([{
code: 4,
name: 'ip4',
path: false,
size: 32,
resolvable: false
}, {
code: 6,
name: 'tcp',
path: false,
size: 16,
resolvable: false
}, {
code: 400,
name: 'unix',
path: true,
size: -1,
resolvable: false
}])
Expand Down Expand Up @@ -663,6 +716,26 @@ describe('helpers', () => {
})
})

describe('.getPath', () => {
it('should return a path for unix', () => {
expect(
multiaddr('/unix/tmp/p2p.sock').getPath()
).to.eql('/tmp/p2p.sock')
})

it('should return a path for unix when other protos exist', () => {
expect(
multiaddr('/ip4/0.0.0.0/tcp/1234/unix/tmp/p2p.sock').getPath()
).to.eql('/tmp/p2p.sock')
})

it('should not return a path when no path proto exists', () => {
expect(
multiaddr('/ip4/0.0.0.0/tcp/1234/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPath()
).to.eql(null)
})
})

describe('multiaddr.isMultiaddr', () => {
it('handles different inputs', () => {
expect(multiaddr.isMultiaddr(multiaddr('/'))).to.be.eql(true)
Expand All @@ -676,6 +749,12 @@ describe('helpers', () => {
describe('resolvable multiaddrs', () => {
describe('.isName', () => {
it('valid name dns', () => {
const str = '/dns/ipfs.io'
const addr = multiaddr(str)
expect(multiaddr.isName(addr)).to.equal(true)
})

it('valid name dnsaddr', () => {
const str = '/dnsaddr/ipfs.io'
const addr = multiaddr(str)
expect(multiaddr.isName(addr)).to.equal(true)
Expand Down

0 comments on commit d4d3d9b

Please sign in to comment.