diff --git a/package.json b/package.json index 588d182..bf9f5cf 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "pull-protocol-buffers": "^0.1.2" }, "devDependencies": { - "aegir": "^13.0.6", + "aegir": "^13.1.0", "libp2p": "^0.20.2", "libp2p-mplex": "^0.7.0", "libp2p-secio": "^0.10.0", diff --git a/src/proto.js b/src/proto.js index c7a8140..b2c6d94 100644 --- a/src/proto.js +++ b/src/proto.js @@ -11,6 +11,16 @@ module.exports = protons(` DISCOVER_RESPONSE = 4; } + enum ResponseStatus { + OK = 0; + E_INVALID_NAMESPACE = 100; + E_INVALID_PEER_INFO = 101; + E_INVALID_TTL = 102; + E_INVALID_COOKIE = 103; + E_NOT_AUTHORIZED = 200; + E_INTERNAL_ERROR = 300; + } + message PeerInfo { optional bytes id = 1; repeated bytes addrs = 2; @@ -22,15 +32,9 @@ module.exports = protons(` optional int64 ttl = 3; // in seconds } - enum RegisterStatus { - OK = 0; - E_INVALID_NAMESPACE = 100; - E_INVALID_PEER_INFO = 101; - E_NOT_AUTHORIZED = 200; - } - message RegisterResponse { - optional RegisterStatus code = 1; + optional ResponseStatus status = 1; + optional string statusText = 2; } message Unregister { @@ -47,6 +51,8 @@ module.exports = protons(` message DiscoverResponse { repeated Register registrations = 1; optional bytes cookie = 2; + optional ResponseStatus status = 3; + optional string statusText = 4; } message Message { diff --git a/src/rpc.js b/src/rpc.js index 2730e7b..5d0781b 100644 --- a/src/rpc.js +++ b/src/rpc.js @@ -12,12 +12,6 @@ const once = require('once') const TIMEOUT = 1000 * 10 // TODO: spec this -const registerErrors = { - 100: 'Invalid namespace provided', - 101: 'Invalid peer-info provided', - 200: 'Not authorized' -} - function wrap (f, t) { let cb = once((...a) => { clearTimeout(timeout) @@ -58,8 +52,8 @@ class RPC { return read(null, next) } else { let e - if (msg.registerResponse.code) { - e = new Error('Server returned error: ' + (registerErrors[msg.registerResponse.code] || '(unknown code)')) + if (msg.registerResponse.status) { + e = new Error('Server returned error: ' + (msg.registerResponse.statusText || '(unknown code)')) } f(e) } @@ -71,6 +65,9 @@ class RPC { log('discover@%s: response ignored, no cb found!', this.id) return read(null, next) } else { + if (msg.discoverResponse.status) { + return setImmediate(() => f(new Error('Server returned error: ' + (msg.discoverResponse.statusText || '(unknown code)')))) + } pi = msg.discoverResponse.registrations.map(p => { try { // TODO: use other values like ttl/ns in peer-info? @@ -81,15 +78,15 @@ class RPC { log('discover@%s: invalid pi returned: %s', this.id, e) } }).filter(Boolean) + setImmediate(() => f(null, { + cookie: msg.discoverResponse.cookie, + peers: pi + })) } } catch (e) { f(e) return next(null, null, e) } - f(null, { - timestamp: msg.discoverResponse.timestamp, - peers: pi - }) break default: // should that disconnect or just get ignored? log('error@%s: sent wrong msg type %s', this.id, msg.type) diff --git a/src/server/rpc.js b/src/server/rpc.js index dcc98b3..fd49d2d 100644 --- a/src/server/rpc.js +++ b/src/server/rpc.js @@ -2,7 +2,7 @@ const pull = require('pull-stream') const ppb = require('pull-protocol-buffers') -const {Message, MessageType, RegisterStatus} = require('../proto') +const {Message, MessageType, ResponseStatus} = require('../proto') const Pushable = require('pull-pushable') const debug = require('debug') const log = debug('libp2p-rendezvous:server:rpc') @@ -12,6 +12,22 @@ const Id = require('peer-id') const MAX_NS_LENGTH = 255 // TODO: spec this const MAX_LIMIT = 1000 // TODO: spec this +const registerErrors = { + 100: 'Invalid namespace provided', + 101: 'Invalid peer-info provided', + 102: 'Invalid TTL provided', + 103: 'Invalid cookie provided', + 200: 'Not authorized', + 300: 'Internal Server Error' +} + +const craftStatus = (status) => { + return { + status, + statusText: registerErrors[status] + } +} + class RPC { constructor (main) { this.main = main @@ -37,9 +53,7 @@ class RPC { log('register@%s: auth err (want %s)', this.id, new Id(msg.register.peer.id).toB58String()) this.source.push({ type: MessageType.REGISTER_RESPONSE, - registerResponse: { - code: RegisterStatus.E_NOT_AUTHORIZED - } + registerResponse: craftStatus(ResponseStatus.E_NOT_AUTHORIZED) }) return read(null, next) } else if (!msg.register.peer.id) { @@ -49,9 +63,7 @@ class RPC { log('register@%s: ns err', this.id) this.source.push({ type: MessageType.REGISTER_RESPONSE, - registerResponse: { - code: RegisterStatus.E_INVALID_NAMESPACE - } + registerResponse: craftStatus(ResponseStatus.E_INVALID_NAMESPACE) }) return read(null, next) } @@ -61,18 +73,14 @@ class RPC { log('register@%s: ok', this.id) this.source.push({ type: MessageType.REGISTER_RESPONSE, - registerResponse: { - code: RegisterStatus.OK - } + registerResponse: craftStatus(ResponseStatus.OK) }) - } catch (e) { // TODO: this might also throw on non-peer-info errors - log('register@%s: other (possibly peer-info related) error', this.id) - log(e) // let's debug the above statement + } catch (e) { + log('register@%s: internal error', this.id) + log(e) this.source.push({ type: MessageType.REGISTER_RESPONSE, - registerResponse: { - code: RegisterStatus.E_INVALID_PEER_INFO - } + registerResponse: craftStatus(ResponseStatus.E_INTERNAL_ERROR) }) return read(null, next) } @@ -88,6 +96,7 @@ class RPC { break case MessageType.DISCOVER: try { + // TODO: add more errors log('discover@%s: discover on %s', this.id, msg.discover.ns) if (msg.discover.limit <= 0 || msg.discover.limit > MAX_LIMIT) msg.discover.limit = MAX_LIMIT const {peers, cookie} = this.main.getNS(msg.discover.ns).getPeers(msg.discover.cookie || Buffer.from(''), msg.discover.limit, this.id) @@ -109,7 +118,13 @@ class RPC { } }) } catch (e) { - return next(null, null, e) + log('discover@%s: internal error', this.id) + log(e) + this.source.push({ + type: MessageType.DISCOVER_RESPONSE, + registerResponse: craftStatus(ResponseStatus.E_INTERNAL_ERROR) + }) + return read(null, next) } break // case MessageType.REGISTER_RESPONSE: