mirror of
https://github.com/jambonz/sbc-sip-sidecar.git
synced 2026-03-21 18:58:05 +00:00
add configurable backup for outbound reg failure (#128)
This commit is contained in:
@@ -42,6 +42,7 @@ const JAMBONES_REGBOT_BATCH_SIZE = process.env.JAMBONES_REGBOT_BATCH_SIZE || 10;
|
|||||||
const OPTIONS_RESPONSE_REMOVE = process.env.OPTIONS_RESPONSE_REMOVE?.split(',').map(Number) || [];
|
const OPTIONS_RESPONSE_REMOVE = process.env.OPTIONS_RESPONSE_REMOVE?.split(',').map(Number) || [];
|
||||||
const REGISTER_RESPONSE_REMOVE = process.env.REGISTER_RESPONSE_REMOVE?.split(',').map(Number) || [];
|
const REGISTER_RESPONSE_REMOVE = process.env.REGISTER_RESPONSE_REMOVE?.split(',').map(Number) || [];
|
||||||
const JAMBONES_REGBOT_USER_AGENT = process.env.JAMBONES_REGBOT_USER_AGENT ;
|
const JAMBONES_REGBOT_USER_AGENT = process.env.JAMBONES_REGBOT_USER_AGENT ;
|
||||||
|
const JAMBONES_REGBOT_FAILURE_RETRY_INTERVAL = process.env.JAMBONES_REGBOT_FAILURE_RETRY_INTERVAL;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
JAMBONES_MYSQL_HOST,
|
JAMBONES_MYSQL_HOST,
|
||||||
@@ -77,5 +78,6 @@ module.exports = {
|
|||||||
JAMBONES_REGBOT_BATCH_SIZE,
|
JAMBONES_REGBOT_BATCH_SIZE,
|
||||||
OPTIONS_RESPONSE_REMOVE,
|
OPTIONS_RESPONSE_REMOVE,
|
||||||
REGISTER_RESPONSE_REMOVE,
|
REGISTER_RESPONSE_REMOVE,
|
||||||
JAMBONES_REGBOT_USER_AGENT
|
JAMBONES_REGBOT_USER_AGENT,
|
||||||
|
JAMBONES_REGBOT_FAILURE_RETRY_INTERVAL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ const {
|
|||||||
JAMBONES_REGBOT_MIN_EXPIRES_INTERVAL,
|
JAMBONES_REGBOT_MIN_EXPIRES_INTERVAL,
|
||||||
JAMBONES_REGBOT_CONTACT_USE_IP,
|
JAMBONES_REGBOT_CONTACT_USE_IP,
|
||||||
REGISTER_RESPONSE_REMOVE,
|
REGISTER_RESPONSE_REMOVE,
|
||||||
JAMBONES_REGBOT_USER_AGENT
|
JAMBONES_REGBOT_USER_AGENT,
|
||||||
|
JAMBONES_REGBOT_FAILURE_RETRY_INTERVAL
|
||||||
} = require('./config');
|
} = require('./config');
|
||||||
const {isValidDomainOrIP, isValidIPv4} = require('./utils');
|
const {isValidDomainOrIP, isValidIPv4} = require('./utils');
|
||||||
const DEFAULT_EXPIRES = (parseInt(JAMBONES_REGBOT_DEFAULT_EXPIRES_INTERVAL) || 3600);
|
const DEFAULT_EXPIRES = (parseInt(JAMBONES_REGBOT_DEFAULT_EXPIRES_INTERVAL) || 3600);
|
||||||
const MIN_EXPIRES = (parseInt(JAMBONES_REGBOT_MIN_EXPIRES_INTERVAL) || 30);
|
const MIN_EXPIRES = (parseInt(JAMBONES_REGBOT_MIN_EXPIRES_INTERVAL) || 30);
|
||||||
|
const FAILURE_RETRY_INTERVAL = (parseInt(JAMBONES_REGBOT_FAILURE_RETRY_INTERVAL) || 300);
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const version = require('../package.json').version;
|
const version = require('../package.json').version;
|
||||||
const useragent = JAMBONES_REGBOT_USER_AGENT || `Jambonz ${version}`;
|
const useragent = JAMBONES_REGBOT_USER_AGENT || `Jambonz ${version}`;
|
||||||
@@ -143,7 +145,7 @@ class Regbot {
|
|||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
this.status = 'fail';
|
this.status = 'fail';
|
||||||
this.logger.info(`${this.aor}: got ${res.status} registering to ${this.ipv4}:${this.port}`);
|
this.logger.info(`${this.aor}: got ${res.status} registering to ${this.ipv4}:${this.port}`);
|
||||||
this.timer = setTimeout(this.register.bind(this, srf), 30 * 1000);
|
this.timer = setTimeout(this.register.bind(this, srf), FAILURE_RETRY_INTERVAL * 1000);
|
||||||
if (REGISTER_RESPONSE_REMOVE.includes(res.status)) {
|
if (REGISTER_RESPONSE_REMOVE.includes(res.status)) {
|
||||||
const { updateCarrierBySid, lookupCarrierBySid } = srf.locals.dbHelpers;
|
const { updateCarrierBySid, lookupCarrierBySid } = srf.locals.dbHelpers;
|
||||||
await updateCarrierBySid(this.voip_carrier_sid, {requires_register: false});
|
await updateCarrierBySid(this.voip_carrier_sid, {requires_register: false});
|
||||||
@@ -245,7 +247,7 @@ class Regbot {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error({ err }, `${this.aor}: Error registering to ${this.ipv4}:${this.port}`);
|
this.logger.error({ err }, `${this.aor}: Error registering to ${this.ipv4}:${this.port}`);
|
||||||
this.timer = setTimeout(this.register.bind(this, srf), 60 * 1000);
|
this.timer = setTimeout(this.register.bind(this, srf), FAILURE_RETRY_INTERVAL * 1000);
|
||||||
updateVoipCarriersRegisterStatus(this.voip_carrier_sid, JSON.stringify({
|
updateVoipCarriersRegisterStatus(this.voip_carrier_sid, JSON.stringify({
|
||||||
status: 'fail',
|
status: 'fail',
|
||||||
reason: err
|
reason: err
|
||||||
|
|||||||
@@ -63,24 +63,30 @@ async function getLocalSIPDomain(logger, srf) {
|
|||||||
*/
|
*/
|
||||||
function getUniqueGateways(gateways, logger) {
|
function getUniqueGateways(gateways, logger) {
|
||||||
const uniqueGatewayKeys = new Set();
|
const uniqueGatewayKeys = new Set();
|
||||||
|
const duplicateCounts = new Map();
|
||||||
|
const uniqueGateways = [];
|
||||||
|
|
||||||
return gateways.filter((gw) => {
|
for (const gw of gateways) {
|
||||||
const key = `${gw.ipv4}:${gw.sip_realm}:${gw.carrier?.register_username}:${gw.carrier?.register_password}`;
|
const key = `${gw.ipv4}:${gw.sip_realm}:${gw.carrier?.register_username}:${gw.carrier?.register_password}`;
|
||||||
if (!gw.carrier?.register_password) {
|
if (!gw.carrier?.register_password) {
|
||||||
logger.info({gw}, `Gateway ${key} does not have a password, ignoring`);
|
logger.info({gw}, `Gateway ${key} does not have a password, ignoring`);
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've already seen this key, it's a duplicate
|
|
||||||
if (uniqueGatewayKeys.has(key)) {
|
if (uniqueGatewayKeys.has(key)) {
|
||||||
logger.info({gw}, `Found duplicate gateway ${key}, ignoring`);
|
duplicateCounts.set(key, (duplicateCounts.get(key) || 1) + 1);
|
||||||
return false;
|
} else {
|
||||||
|
uniqueGatewayKeys.add(key);
|
||||||
|
uniqueGateways.push(gw);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, add it to our Set and keep this gateway
|
// Log summary for each duplicate gateway
|
||||||
uniqueGatewayKeys.add(key);
|
for (const [key, count] of duplicateCounts) {
|
||||||
return true;
|
logger.info({key, count}, `Found ${count} duplicate gateways for ${key}, ignoring duplicates`);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return uniqueGateways;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = async(logger, srf) => {
|
module.exports = async(logger, srf) => {
|
||||||
@@ -222,7 +228,7 @@ const updateCarrierRegbots = async(logger, srf) => {
|
|||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
|
|
||||||
debug('updateCarrierRegbots: got new or changed carriers');
|
debug('updateCarrierRegbots: got new or changed carriers');
|
||||||
logger.info({gws}, 'updateCarrierRegbots: got new or changed carriers');
|
logger.info({count: gws.length}, 'updateCarrierRegbots: got new or changed carriers');
|
||||||
|
|
||||||
// Clear and repopulate arrays in chunks to avoid argument limit
|
// Clear and repopulate arrays in chunks to avoid argument limit
|
||||||
carriers.length = 0;
|
carriers.length = 0;
|
||||||
|
|||||||
60
package-lock.json
generated
60
package-lock.json
generated
@@ -19,7 +19,7 @@
|
|||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"drachtio-mw-registration-parser": "^0.1.2",
|
"drachtio-mw-registration-parser": "^0.1.2",
|
||||||
"drachtio-mw-response-time": "^1.0.2",
|
"drachtio-mw-response-time": "^1.0.2",
|
||||||
"drachtio-srf": "^5.0.5",
|
"drachtio-srf": "^5.0.18",
|
||||||
"pino": "^10.1.0",
|
"pino": "^10.1.0",
|
||||||
"short-uuid": "^4.2.2"
|
"short-uuid": "^4.2.2"
|
||||||
},
|
},
|
||||||
@@ -1366,9 +1366,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/delegates": {
|
"node_modules/delegates": {
|
||||||
"version": "0.1.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
"integrity": "sha512-tPYr58xmVlUWcL8zPk6ZAxP6XqiYx5IIn395dkeER12JmMy8P6ipGKnUvgD++g8+uCaALfs/CRERixvKBu1pow=="
|
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/denque": {
|
"node_modules/denque": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@@ -1405,32 +1406,50 @@
|
|||||||
"integrity": "sha512-d+DtKuqhpkSBBkRfwcgS3x26T3lrdgo86yVWZ4wy+K8RtS1faT3hgLBq9EPEYSDkcw76r4klvdDWPhTrPqGAQw=="
|
"integrity": "sha512-d+DtKuqhpkSBBkRfwcgS3x26T3lrdgo86yVWZ4wy+K8RtS1faT3hgLBq9EPEYSDkcw76r4klvdDWPhTrPqGAQw=="
|
||||||
},
|
},
|
||||||
"node_modules/drachtio-srf": {
|
"node_modules/drachtio-srf": {
|
||||||
"version": "5.0.13",
|
"version": "5.0.18",
|
||||||
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-5.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-5.0.18.tgz",
|
||||||
"integrity": "sha512-IG62MLLzhXjQtbjX6T6I8jXK6QhWQwsblkO3+F2Zhcu4lXBO3W12rrKyAPsw6GimRSSXIkvMbn5/je8AU/xehQ==",
|
"integrity": "sha512-gm8kc+w0FuWozR6oprcMqa2oPf9dpMABOrbUZle9XcsvJ+DZxpOk11gBBmtj12oSjPgb5hIi+jxzmI6blKVDRw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^3.2.7",
|
"debug": "^4.4.3",
|
||||||
"delegates": "^0.1.0",
|
"delegates": "^1.0.0",
|
||||||
"node-noop": "^0.0.1",
|
"node-noop": "^1.0.0",
|
||||||
"only": "^0.0.2",
|
"only": "^0.0.2",
|
||||||
"sdp-transform": "^2.15.0",
|
"sdp-transform": "^2.15.0",
|
||||||
"short-uuid": "^4.2.2",
|
"short-uuid": "^5.2.0",
|
||||||
"sip-methods": "^0.3.0",
|
"sip-methods": "^0.3.0",
|
||||||
"sip-status": "^0.1.0",
|
"sip-status": "^0.1.0",
|
||||||
"utils-merge": "^1.0.0",
|
"utils-merge": "^1.0.1",
|
||||||
"uuid-random": "^1.3.2"
|
"uuid-random": "^1.3.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18.x"
|
"node": ">= 18.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/drachtio-srf/node_modules/debug": {
|
"node_modules/drachtio-srf/node_modules/short-uuid": {
|
||||||
"version": "3.2.7",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-5.2.0.tgz",
|
||||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
"integrity": "sha512-296/Nzi4DmANh93iYBwT4NoYRJuHnKEzefrkSagQbTH/A6NTaB68hSPDjm5IlbI5dx9FXdmtqPcj6N5H+CPm6w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.1"
|
"any-base": "^1.1.0",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/drachtio-srf/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dunder-proto": {
|
"node_modules/dunder-proto": {
|
||||||
@@ -3313,9 +3332,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/node-noop": {
|
"node_modules/node-noop": {
|
||||||
"version": "0.0.1",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-noop/-/node-noop-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-noop/-/node-noop-1.0.0.tgz",
|
||||||
"integrity": "sha512-kAUvIRxZyDYFTLqGj+7zqXduG89vtqGmNMt9qDMvYH3H8uNTCOTz5ZN1q2Yg8++fWbzv+ERtYVqaOH42Ag5OpA=="
|
"integrity": "sha512-1lpWqKwZ9yUosQfW1uy3jm6St4ZbmeDKKGmdzwzedbyBI4LgHtGyL1ofDdqiSomgaYaSERi+qWtj64huJQjl7g==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/node-object-hash": {
|
"node_modules/node-object-hash": {
|
||||||
"version": "2.3.10",
|
"version": "2.3.10",
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"drachtio-mw-registration-parser": "^0.1.2",
|
"drachtio-mw-registration-parser": "^0.1.2",
|
||||||
"drachtio-mw-response-time": "^1.0.2",
|
"drachtio-mw-response-time": "^1.0.2",
|
||||||
"drachtio-srf": "^5.0.5",
|
"drachtio-srf": "^5.0.18",
|
||||||
"pino": "^10.1.0",
|
"pino": "^10.1.0",
|
||||||
"short-uuid": "^4.2.2"
|
"short-uuid": "^4.2.2"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user