diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 194fa6c..e560431 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,12 +6,17 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: lts/* + node-version: 20.x - run: npm ci - run: npm run jslint + - name: Install Docker Compose + run: | + sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + docker-compose --version - run: npm test diff --git a/app.js b/app.js index 387250f..9ea4cb0 100644 --- a/app.js +++ b/app.js @@ -50,7 +50,8 @@ const { lookupSipGatewaysByCarrier, lookupCarrierBySid, queryCallLimits, - lookupCarrierByAccountLcr + lookupCarrierByAccountLcr, + lookupSystemInformation } = require('@jambonz/db-helpers')({ host: process.env.JAMBONES_MYSQL_HOST, port: process.env.JAMBONES_MYSQL_PORT || 3306, @@ -84,6 +85,7 @@ srf.locals = {...srf.locals, queryCdrs, activeCallIds, idleEmitter, + privateNetworkCidr: process.env.PRIVATE_VOIP_NETWORK_CIDR || null, dbHelpers: { ping, lookupOutboundCarrierForAccount, @@ -94,7 +96,8 @@ srf.locals = {...srf.locals, lookupSipGatewaysByCarrier, lookupCarrierBySid, queryCallLimits, - lookupCarrierByAccountLcr + lookupCarrierByAccountLcr, + lookupSystemInformation }, realtimeDbHelpers: { client: redisClient, @@ -184,10 +187,18 @@ if (process.env.K8S || process.env.HTTP_PORT) { }); } if ('test' !== process.env.NODE_ENV) { - /* update call stats periodically */ - setInterval(() => { + /* update call stats periodically as well as definition of private network cidr */ + setInterval(async() => { stats.gauge('sbc.sip.calls.count', activeCallIds.size, ['direction:outbound', `instance_id:${process.env.INSTANCE_ID || 0}`]); + + const r = await lookupSystemInformation(); + if (r) { + if (r.private_network_cidr !== srf.locals.privateNetworkCidr) { + logger.info(`updating private network cidr from ${srf.locals.privateNetworkCidr} to ${r.private_network_cidr}`); + srf.locals.privateNetworkCidr = r.private_network_cidr; + } + } }, 20000); } @@ -262,4 +273,4 @@ function handle(signal) { } } -module.exports = {srf}; +module.exports = {srf, logger}; diff --git a/lib/utils.js b/lib/utils.js index c2f62f3..fd7fb00 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -4,9 +4,6 @@ const debug = require('debug')('jambonz:sbc-outbound'); const CIDRMatcher = require('cidr-matcher'); const dns = require('dns'); -const cidrMatcher = process.env.PRIVATE_VOIP_NETWORK_CIDR ? - new CIDRMatcher(process.env.PRIVATE_VOIP_NETWORK_CIDR.split(',')) : null; - function makeRtpEngineOpts(req, srcIsUsingSrtp, dstIsUsingSrtp, padCrypto, teams) { const from = req.getParsedHeader('from'); const rtpCopy = JSON.parse(JSON.stringify(rtpCharacteristics)); @@ -191,8 +188,12 @@ const nudgeCallCounts = async(logger, sids, nudgeOperator, writers) => { }; const isPrivateVoipNetwork = async(uri) => { - if (cidrMatcher) { + const {srf, logger} = require('..'); + const {privateNetworkCidr} = srf.locals; + + if (privateNetworkCidr) { try { + const matcher = new CIDRMatcher(privateNetworkCidr.split(',')); const arr = /sips?:.*@(.*?)(:\d+)?(;.*)$/.exec(uri); if (arr) { const input = arr[1]; @@ -203,12 +204,15 @@ const isPrivateVoipNetwork = async(uri) => { addresses = await dns.resolve4(input); } for (const ip of addresses) { - if (cidrMatcher.contains(ip)) { + if (matcher.contains(ip)) { return true; } } } - } catch (err) {} + } catch (err) { + logger.info({err, privateNetworkCidr}, + 'Error checking private network CIDR, probably misconfigured must be a comma separated list of CIDRs'); + } } return false; }; diff --git a/package-lock.json b/package-lock.json index f1a08aa..47d4ab1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.9.0", "license": "MIT", "dependencies": { - "@jambonz/db-helpers": "^0.9.6", + "@jambonz/db-helpers": "^0.9.7", "@jambonz/http-health-check": "^0.0.1", "@jambonz/mw-registrar": "0.2.7", "@jambonz/realtimedb-helpers": "^0.8.9", @@ -578,13 +578,13 @@ } }, "node_modules/@jambonz/db-helpers": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.6.tgz", - "integrity": "sha512-uvtkqdP6GP6KSaM7eo2jcU1k0R6Ymodhl0RH/XiNESgIhZ7sx7ZnMQtrZQVVmzrJ429H7q8dQqgcB2YhAyEK+A==", + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.7.tgz", + "integrity": "sha512-5qN/CJZJXpbMkMn+8gFn8PpQ0ZImZxp1EjKyxLUlmMn+xgjeNb29c3pjeVt/6EQnBB65jAax6TNsVzVIfpvE2w==", "dependencies": { "cidr-matcher": "^2.1.1", "debug": "^4.3.4", - "mysql2": "^3.10.3", + "mysql2": "^3.11.0", "node-object-hash": "^2.3.10", "uuid": "^8.3.2" } @@ -3563,9 +3563,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mysql2": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.3.tgz", - "integrity": "sha512-k43gmH9i79rZD4hGPdj7pDuT0UBiFjs4UzXEy1cJrV0QqcSABomoLwvejqdbcXN+Vd7gi999CVM6o9vCPKq29g==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.0.tgz", + "integrity": "sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==", "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", diff --git a/package.json b/package.json index c2697a8..7d89bc7 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "jslint": "eslint app.js lib --fix" }, "dependencies": { - "@jambonz/db-helpers": "^0.9.6", + "@jambonz/db-helpers": "^0.9.7", "@jambonz/realtimedb-helpers": "^0.8.9", "@jambonz/http-health-check": "^0.0.1", "@jambonz/mw-registrar": "0.2.7",