Skip to content

Commit

Permalink
feat: add onion and onion3 support (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
ricott1 authored and jacobheun committed Jun 5, 2019
1 parent 44eac00 commit b606df3
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"class-is": "^1.1.0",
"ip": "^1.1.5",
"is-ip": "^2.0.0",
"varint": "^5.0.0"
"varint": "^5.0.0",
"hi-base32": "~0.5.0"
},
"devDependencies": {
"aegir": "^18.2.0",
Expand All @@ -44,6 +45,7 @@
},
"contributors": [
"Alan Shaw <alan@tableflip.io>",
"Alessandro Ricottone <ricott2@gmail.com>",
"Chris Anderson <jchris@gmail.com>",
"David Dias <daviddias.p@gmail.com>",
"Diogo Silva <fsdiogo@gmail.com>",
Expand Down
55 changes: 55 additions & 0 deletions src/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const ip = require('ip')
const isIp = require('is-ip')
const protocols = require('./protocols-table')
const bs58 = require('bs58')
const base32 = require('hi-base32')
const varint = require('varint')

module.exports = Convert
Expand Down Expand Up @@ -39,6 +40,10 @@ Convert.toString = function convertToString (proto, buf) {

case 421: // ipfs
return buf2mh(buf)
case 444: // onion
return buf2onion(buf)
case 445: // onion3
return buf2onion(buf)
default:
return buf.toString('hex') // no clue. convert to hex
}
Expand Down Expand Up @@ -67,6 +72,10 @@ Convert.toBuffer = function convertToBuffer (proto, str) {

case 421: // ipfs
return mh2buf(str)
case 444: // onion
return onion2buf(str)
case 445: // onion3
return onion32buf(str)
default:
return Buffer.from(str, 'hex') // no clue. convert from hex
}
Expand Down Expand Up @@ -131,3 +140,49 @@ function buf2mh (buf) {

return bs58.encode(address)
}

function onion2buf (str) {
const addr = str.split(':')
if (addr.length !== 2) {
throw new Error('failed to parse onion addr: ' + addr + ' does not contain a port number')
}
if (addr[0].length !== 16) {
throw new Error('failed to parse onion addr: ' + addr[0] + ' not a Tor onion address.')
}
const buf = Buffer.from(base32.decode.asBytes(addr[0].toUpperCase()))

// onion port number
const port = parseInt(addr[1], 10)
if (port < 1 || port > 65536) {
throw new Error('Port number is not in range(1, 65536)')
}
const portBuf = port2buf(port)
return Buffer.concat([buf, portBuf])
}

function onion32buf (str) {
const addr = str.split(':')
if (addr.length !== 2) {
throw new Error('failed to parse onion addr: ' + addr + ' does not contain a port number')
}
if (addr[0].length !== 56) {
throw new Error('failed to parse onion addr: ' + addr[0] + ' not a Tor onion3 address.')
}
const buf = Buffer.from(base32.decode.asBytes(addr[0].toUpperCase()))

// onion port number
const port = parseInt(addr[1], 10)
if (port < 1 || port > 65536) {
throw new Error('Port number is not in range(1, 65536)')
}
const portBuf = port2buf(port)
return Buffer.concat([buf, portBuf])
}

function buf2onion (buf) {
const addrBytes = buf.slice(0, buf.length - 2)
const portBytes = buf.slice(buf.length - 2)
const addr = base32.encode(addrBytes).toString('ascii').toLowerCase()
const port = buf2port(portBytes)
return addr + ':' + port
}
44 changes: 44 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,50 @@ describe('variants', () => {
expect(addr.toString()).to.equal(str)
})

it('onion', () => {
const str = '/onion/timaq4ygg2iegci7:1234'
const addr = multiaddr(str)
expect(addr).to.have.property('buffer')
expect(addr.toString()).to.equal(str)
})

it('onion bad length', () => {
const str = '/onion/timaq4ygg2iegci:80'
expect(() => multiaddr(str)).to.throw()
})

it('onion bad port', () => {
const str = '/onion/timaq4ygg2iegci7:-1'
expect(() => multiaddr(str)).to.throw()
})

it('onion no port', () => {
const str = '/onion/timaq4ygg2iegci7'
expect(() => multiaddr(str)).to.throw()
})

it('onion3', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:1234'
const addr = multiaddr(str)
expect(addr).to.have.property('buffer')
expect(addr.toString()).to.equal(str)
})

it('onion3 bad length', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopyyd:1234'
expect(() => multiaddr(str)).to.throw()
})

it('onion3 bad port', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:-1'
expect(() => multiaddr(str)).to.throw()
})

it('onion3 no port', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd'
expect(() => multiaddr(str)).to.throw()
})

it('p2p-circuit', () => {
const str = '/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
const addr = multiaddr(str)
Expand Down

0 comments on commit b606df3

Please sign in to comment.