diff --git a/lib/sip-trunk-options-ping.js b/lib/sip-trunk-options-ping.js index 42b7593..e518b21 100644 --- a/lib/sip-trunk-options-ping.js +++ b/lib/sip-trunk-options-ping.js @@ -1,4 +1,4 @@ -const { addSipGatewayToBlacklist } = require('./utils'); +const { addSipGatewayToBlacklist, removeSipGatewayFromBlacklist, isSipGatewayBlacklisted } = require('./utils'); const send_options_gateways = []; const send_options_bots = []; @@ -12,6 +12,7 @@ class OptionsBot { this.port = gateway.port; this.protocol = gateway.protocol; this.expiry = (process.env.SEND_OPTIONS_PING_INTERVAL || 60); + this.blacklist_expiry = (process.env.OPTIONS_PING_TTL || 300); const useSipsScheme = gateway.protocol.includes('tls') && gateway.use_sips_scheme; const isIPv4 = /[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/.test(gateway.ipv4); @@ -34,29 +35,41 @@ class OptionsBot { req.on('response', async(res) => { if (res.status !== 200) { this.logger.info(`Received Options response ${res.status} for ${this.uri}`); - await addSipGatewayToBlacklist(realtimeDbHelpers.client, logger, this.sip_gateway_sid, this.expiry); - const carrier = await lookupCarrierBySid(this.voip_carrier_sid); - if (carrier) { - writeAlerts({ - account_sid: carrier.account_sid, - service_provider_sid: carrier.service_provider_sid, - // eslint-disable-next-line max-len - message: `Options ping ${this.ipv4}${this.port ? `:${this.port}` : ''};transport=${this.protocol} unsuccessfully, received: ${res.status}` - }); + // Check if the SIP gateway is not already blacklisted + if (!await isSipGatewayBlacklisted(realtimeDbHelpers.client, logger, this.sip_gateway_sid)) { + // Add the gateway to the blacklist since it failed the OPTIONS ping + await addSipGatewayToBlacklist(realtimeDbHelpers.client, logger, this.sip_gateway_sid, + this.blacklist_expiry); + const carrier = await lookupCarrierBySid(this.voip_carrier_sid); + if (carrier) { + writeAlerts({ + account_sid: carrier.account_sid, + service_provider_sid: carrier.service_provider_sid, + // eslint-disable-next-line max-len + message: `Options ping ${this.ipv4}${this.port ? `:${this.port}` : ''};transport=${this.protocol} unsuccessfully, received: ${res.status}` + }); + } + } + } else { + // If the gateway is blacklisted, remove it from the blacklist as we have successfully pinged it + if (await isSipGatewayBlacklisted(realtimeDbHelpers.client, logger, this.sip_gateway_sid)) { + await removeSipGatewayFromBlacklist(realtimeDbHelpers.client, logger, this.sip_gateway_sid); } } }); } catch (err) { this.logger.error({ err }, `Error Options ping to ${this.uri}`); - await addSipGatewayToBlacklist(realtimeDbHelpers.client, logger, this.sip_gateway_sid, this.expiry); - const carrier = await lookupCarrierBySid(this.voip_carrier_sid); - if (carrier) { - writeAlerts({ - account_sid: carrier.account_sid, - service_provider_sid: carrier.service_provider_sid, - // eslint-disable-next-line max-len - message: `Options ping ${this.ipv4}${this.port ? `:${this.port}` : ''};transport=${this.protocol} unsuccessfully, error: ${err}` - }); + if (!await isSipGatewayBlacklisted(realtimeDbHelpers.client, logger, this.sip_gateway_sid)) { + await addSipGatewayToBlacklist(realtimeDbHelpers.client, logger, this.sip_gateway_sid, this.blacklist_expiry); + const carrier = await lookupCarrierBySid(this.voip_carrier_sid); + if (carrier) { + writeAlerts({ + account_sid: carrier.account_sid, + service_provider_sid: carrier.service_provider_sid, + // eslint-disable-next-line max-len + message: `Options ping ${this.ipv4}${this.port ? `:${this.port}` : ''};transport=${this.protocol} unsuccessfully, error: ${err}` + }); + } } } } diff --git a/lib/utils.js b/lib/utils.js index ceb5e9f..7ac10a2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -20,13 +20,31 @@ function makeBlacklistGatewayKey(key) { async function addSipGatewayToBlacklist(client, logger, sip_gateway_sid, expired) { try { - await client.setex(makeBlacklistGatewayKey(sip_gateway_sid), expired, ''); + await client.setex(makeBlacklistGatewayKey(sip_gateway_sid), expired, '1'); logger.info(`addSipGatewayToBlacklist: added ${sip_gateway_sid} to blacklist`); } catch (err) { logger.error({err}, `addSipGatewayToBlacklist: Error add ${sip_gateway_sid} to blacklist`); } } +async function removeSipGatewayFromBlacklist(client, logger, sip_gateway_sid) { + try { + await client.del(makeBlacklistGatewayKey(sip_gateway_sid)); + logger.info(`removeSipGatewayFromBlacklist: removed ${sip_gateway_sid} from blacklist`); + } catch (err) { + logger.error({err}, `removeSipGatewayFromBlacklist: Error removing ${sip_gateway_sid} from blacklist`); + } +} +async function isSipGatewayBlacklisted(client, logger, sip_gateway_sid) { + try { + const exists = await client.get(makeBlacklistGatewayKey(sip_gateway_sid)); + return exists === '1'; + } catch (err) { + logger.error({err}, `isSipGatewayBlacklisted: Error checking if ${sip_gateway_sid} is blacklisted`); + return false; + } +} + /* Regex pattern to match valid IPv4 addresses (0.0.0.0 to 255.255.255.255) */ const ipv4Pattern = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; @@ -58,6 +76,8 @@ module.exports = { isUacBehindNat, getSipProtocol, addSipGatewayToBlacklist, + removeSipGatewayFromBlacklist, + isSipGatewayBlacklisted, NAT_EXPIRES: 30, isValidIPv4, isValidDomainOrIP,