|
|
@ -2,13 +2,14 @@ const FIFO = require('fast-fifo') |
|
|
|
const sodium = require('sodium-universal') |
|
|
|
const c = require('compact-encoding') |
|
|
|
const bind = require('bind-easy') |
|
|
|
const b4a = require('b4a') |
|
|
|
const peer = require('./peer') |
|
|
|
const { INVALID_TOKEN, TIMEOUT, DESTROY } = require('./errors') |
|
|
|
|
|
|
|
const VERSION = 0b11 |
|
|
|
const RESPONSE_ID = (0b0001 << 4) | VERSION |
|
|
|
const REQUEST_ID = (0b0000 << 4) | VERSION |
|
|
|
const TMP = Buffer.alloc(32) |
|
|
|
const TMP = b4a.alloc(32) |
|
|
|
const EMPTY_ARRAY = [] |
|
|
|
|
|
|
|
module.exports = class IO { |
|
|
@ -46,7 +47,7 @@ module.exports = class IO { |
|
|
|
if (buffer[0] === REQUEST_ID) { |
|
|
|
const req = Request.decode(this, socket, from, state) |
|
|
|
if (req === null) return |
|
|
|
if (req.token !== null && !req.token.equals(this.token(req.from, 1)) && !req.token.equals(this.token(req.from, 0))) { |
|
|
|
if (req.token !== null && !b4a.equals(req.token, this.token(req.from, 1)) && !b4a.equals(req.token, this.token(req.from, 0))) { |
|
|
|
req.error(INVALID_TOKEN, { token: true }) |
|
|
|
return |
|
|
|
} |
|
|
@ -82,14 +83,14 @@ module.exports = class IO { |
|
|
|
|
|
|
|
token (addr, i) { |
|
|
|
if (this._secrets === null) { |
|
|
|
const buf = Buffer.alloc(64) |
|
|
|
const buf = b4a.alloc(64) |
|
|
|
this._secrets = [buf.subarray(0, 32), buf.subarray(32, 64)] |
|
|
|
sodium.randombytes_buf(this._secrets[0]) |
|
|
|
sodium.randombytes_buf(this._secrets[1]) |
|
|
|
} |
|
|
|
|
|
|
|
const token = Buffer.allocUnsafe(32) |
|
|
|
sodium.crypto_generichash(token, Buffer.from(addr.host), this._secrets[i]) |
|
|
|
const token = b4a.allocUnsafe(32) |
|
|
|
sodium.crypto_generichash(token, b4a.from(addr.host), this._secrets[i]) |
|
|
|
return token |
|
|
|
} |
|
|
|
|
|
|
@ -309,7 +310,7 @@ class Request { |
|
|
|
if (error > 0) c.uint.preencode(state, error) |
|
|
|
if (value) c.buffer.preencode(state, value) |
|
|
|
|
|
|
|
state.buffer = Buffer.allocUnsafe(state.end) |
|
|
|
state.buffer = b4a.allocUnsafe(state.end) |
|
|
|
state.buffer[state.start++] = RESPONSE_ID |
|
|
|
state.buffer[state.start++] = (id ? 1 : 0) | (token ? 2 : 0) | (closerNodes.length > 0 ? 4 : 0) | (error > 0 ? 8 : 0) | (value ? 16 : 0) |
|
|
|
|
|
|
@ -337,7 +338,7 @@ class Request { |
|
|
|
if (this.target) state.end += 32 |
|
|
|
if (value) c.buffer.preencode(state, value) |
|
|
|
|
|
|
|
state.buffer = Buffer.allocUnsafe(state.end) |
|
|
|
state.buffer = b4a.allocUnsafe(state.end) |
|
|
|
state.buffer[state.start++] = REQUEST_ID |
|
|
|
state.buffer[state.start++] = (id ? 1 : 0) | (token ? 2 : 0) | (this.internal ? 4 : 0) | (this.target ? 8 : 0) | (value ? 16 : 0) |
|
|
|
|
|
|
@ -420,5 +421,5 @@ function decodeReply (from, state) { |
|
|
|
} |
|
|
|
|
|
|
|
function validateId (id, from) { |
|
|
|
return peer.id(from.host, from.port, TMP).equals(id) ? id : null |
|
|
|
return b4a.equals(peer.id(from.host, from.port, TMP), id) ? id : null |
|
|
|
} |
|
|
|