From 0ef73c8956699de8f51c61f9e88a820c57bed0b7 Mon Sep 17 00:00:00 2001 From: Yilun Date: Sat, 20 Jun 2020 17:22:37 -0700 Subject: [PATCH] Add force keepalive using random generated client Signed-off-by: Yilun --- lib/index.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/index.js | 52 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5eb6dd0..24e6dcc 100644 --- a/lib/index.js +++ b/lib/index.js @@ -64,10 +64,15 @@ let argv = _yargs.default.command('$0', 'start nshd').command('addr', 'show addr describe: 'show executed cmd in console', type: 'boolean', default: false +}).option('must-keepalive', { + describe: 'nshd will exit if keepalive failed', + type: 'boolean', + default: false }).help('help').alias('h', 'help').wrap(Math.min(120, _yargs.default.terminalWidth())).argv; const isWindows = _os.default.platform() === 'win32'; const pingInterval = 20000; +const forcePingInterval = 60000; const ptyCols = 120; const ptyRows = 30; const sessionFlushIntervalInUse = 10; @@ -218,6 +223,7 @@ function getAuthorizedUser(src) { } const client = new _nknSdk.default.MultiClient({ + originalClient: true, seed: wallet.getSeed(), identifier: identifier }); @@ -295,22 +301,64 @@ client.onConnect(() => { } let lastUpdateTime = new Date(); - setInterval(async function () { + setInterval(async () => { try { await client.send(client.addr, ''); lastUpdateTime = new Date(); } catch (e) { console.warn('Multiclient ping error:', e); + let t = new Date().getTime() - lastUpdateTime.getTime(); + + if (argv.mustKeepalive && t > pingInterval * 5) { + process.exit(1); + } - if (new Date().getTime() - lastUpdateTime.getTime() > pingInterval * 3) { + if (t > pingInterval * 3) { console.log('Multiclient keepalive timeout, trying to reconnect...'); for (let c of Object.values(client.clients)) { - c.reconnect(); + c._reconnect(); } } } }, pingInterval); + let lastForceUpdateTime = new Date(); + setInterval(async () => { + let tempIdentifier = _nknSdk.default.util.randomBytesHex(4); + + if (identifier) { + tempIdentifier += '.' + identifier; + } + + let tempClient = new _nknSdk.default.MultiClient({ + originalClient: true, + seed: wallet.getSeed(), + identifier: tempIdentifier + }); + tempClient.onConnect(() => { + setTimeout(async () => { + try { + await tempClient.send(client.addr, ''); + lastForceUpdateTime = new Date(); + } catch (e) { + console.warn('Force ping error:', e); + let t = new Date().getTime() - lastForceUpdateTime.getTime(); + + if (argv.mustKeepalive && t > forcePingInterval * 5) { + process.exit(1); + } + + if (t > forcePingInterval * 3) { + console.log('Force keepalive timeout, trying to reconnect...'); + + for (let c of Object.values(client.clients)) { + c._reconnect(); + } + } + } + }, 3000); + }); + }, forcePingInterval); }); client.onMessage(async ({ src, @@ -323,7 +371,7 @@ client.onMessage(async ({ return false; } - if (src === client.addr) { + if (src.endsWith(client.getPublicKey()) && !payload) { return; } diff --git a/src/index.js b/src/index.js index 13f4170..8891d02 100644 --- a/src/index.js +++ b/src/index.js @@ -66,6 +66,11 @@ let argv = yargs type: 'boolean', default: false, }) + .option('must-keepalive', { + describe: 'nshd will exit if keepalive failed', + type: 'boolean', + default: false, + }) .help('help') .alias('h', 'help') .wrap(Math.min(120, yargs.terminalWidth())) @@ -73,6 +78,7 @@ let argv = yargs const isWindows = os.platform() === 'win32' const pingInterval = 20000 +const forcePingInterval = 60000 const ptyCols = 120 const ptyRows = 30 const sessionFlushIntervalInUse = 10 @@ -200,6 +206,7 @@ function getAuthorizedUser(src) { } const client = new nkn.MultiClient({ + originalClient: true, seed: wallet.getSeed(), identifier: identifier, }) @@ -276,20 +283,57 @@ client.onConnect(() => { } let lastUpdateTime = new Date() - setInterval(async function () { + setInterval(async () => { try { await client.send(client.addr, '') lastUpdateTime = new Date() } catch (e) { console.warn('Multiclient ping error:', e) - if (new Date().getTime() - lastUpdateTime.getTime() > pingInterval * 3) { + let t = new Date().getTime() - lastUpdateTime.getTime() + if (argv.mustKeepalive && t > pingInterval * 5) { + process.exit(1) + } + if (t > pingInterval * 3) { console.log('Multiclient keepalive timeout, trying to reconnect...') for (let c of Object.values(client.clients)) { - c.reconnect() + c._reconnect() } } } }, pingInterval) + + let lastForceUpdateTime = new Date() + setInterval(async () => { + let tempIdentifier = nkn.util.randomBytesHex(4) + if (identifier) { + tempIdentifier += '.' + identifier + } + let tempClient = new nkn.MultiClient({ + originalClient: true, + seed: wallet.getSeed(), + identifier: tempIdentifier, + }); + tempClient.onConnect(() => { + setTimeout(async () => { + try { + await tempClient.send(client.addr, '') + lastForceUpdateTime = new Date() + } catch (e) { + console.warn('Force ping error:', e) + let t = new Date().getTime() - lastForceUpdateTime.getTime() + if (argv.mustKeepalive && t > forcePingInterval * 5) { + process.exit(1) + } + if (t > forcePingInterval * 3) { + console.log('Force keepalive timeout, trying to reconnect...') + for (let c of Object.values(client.clients)) { + c._reconnect() + } + } + } + }, 3000); + }) + }, forcePingInterval) }) client.onMessage(async ({ src, payload, payloadType, isEncrypted }) => { @@ -298,7 +342,7 @@ client.onMessage(async ({ src, payload, payloadType, isEncrypted }) => { return false } - if (src === client.addr) { + if (src.endsWith(client.getPublicKey()) && !payload) { return }