Compare commits

...
3 Commits
Author SHA1 Message Date
Dave Horton e641c590b2 Fix/cidr error handling (#102)
* fix docker build

* catch error from CIDR which can happen with invalid sip gateway data
2023-05-31 09:11:53 -04:00
Dave Horton 8448e003f6 update siprec-client-utils 2023-05-29 09:23:37 -04:00
Dave Horton f6e071f31e standardize on passing .query args as array (#99) 2023-05-22 09:56:48 -04:00
4 changed files with 42 additions and 30 deletions
+3 -1
View File
@@ -2,6 +2,8 @@ name: Docker
on:
push:
branches:
- main
tags:
- '*'
@@ -18,7 +20,7 @@ jobs:
- name: prepare tag
id: prepare_tag
run: |
IMAGE_ID=$GITHUB_REPOSITORY
IMAGE_ID=jambonz/sbc-inbound
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
+23 -13
View File
@@ -11,6 +11,8 @@ vc.application_sid, sg.inbound, sg.outbound, sg.is_active, sg.ipv4, sg.netmask
FROM sip_gateways sg, voip_carriers vc, accounts acc
WHERE acc.sip_realm = ?
AND vc.account_sid = acc.account_sid
AND vc.is_active = 1
AND sg.inbound = 1
AND sg.voip_carrier_sid = vc.voip_carrier_sid`;
const sqlSelectAllCarriersForSPByRealm =
@@ -20,6 +22,8 @@ FROM sip_gateways sg, voip_carriers vc, accounts acc
WHERE acc.sip_realm = ?
AND vc.service_provider_sid = acc.service_provider_sid
AND vc.account_sid IS NULL
AND vc.is_active = 1
AND sg.inbound = 1
AND sg.voip_carrier_sid = vc.voip_carrier_sid`;
const sqlSelectAllGatewaysForSP =
@@ -37,6 +41,8 @@ vc.application_sid, sg.inbound, sg.outbound, sg.is_active, sg.ipv4, sg.netmask
FROM sip_gateways sg, voip_carriers vc, accounts acc
WHERE acc.account_sid = ?
AND vc.account_sid = acc.account_sid
AND vc.is_active = 1
AND sg.inbound = 1
AND sg.voip_carrier_sid = vc.voip_carrier_sid`;
const sqlAccountByRealm = 'SELECT * from accounts WHERE sip_realm = ?';
@@ -68,11 +74,15 @@ AND vc.is_active = 1
AND vc.register_sip_realm = ?
AND vc.register_username = ?`;
const gatewayMatchesSourceAddress = (source_address, gw) => {
const gatewayMatchesSourceAddress = (logger, source_address, gw) => {
if (32 === gw.netmask && gw.ipv4 === source_address) return true;
if (gw.netmask < 32) {
const matcher = new CIDRMatcher([`${gw.ipv4}/${gw.netmask}`]);
return matcher.contains(source_address);
try {
const matcher = new CIDRMatcher([`${gw.ipv4}/${gw.netmask}`]);
return matcher.contains(source_address);
} catch (err) {
logger.info({err, gw}, 'gatewayMatchesSourceAddress: Error parsing netmask');
}
}
return false;
};
@@ -137,12 +147,12 @@ module.exports = (srf, logger) => {
*/
/* get all the carriers and gateways for the account owning this sip realm */
const [gwAcc] = await pp.query(sqlSelectAllCarriersForAccountByRealm, uri.host);
const [gwAcc] = await pp.query(sqlSelectAllCarriersForAccountByRealm, [uri.host]);
const [gwSP] = gwAcc.length ? [[]] : await pp.query(sqlSelectAllCarriersForSPByRealm, uri.host);
const gw = gwAcc.concat(gwSP);
const selected = gw.find(gatewayMatchesSourceAddress.bind(null, req.source_address));
const selected = gw.find(gatewayMatchesSourceAddress.bind(null, logger, req.source_address));
if (selected) {
const [a] = await pp.query(sqlAccountByRealm, uri.host);
const [a] = await pp.query(sqlAccountByRealm, [uri.host]);
if (0 === a.length) return failure;
return {
fromCarrier: true,
@@ -161,14 +171,14 @@ module.exports = (srf, logger) => {
user: uri.user
}, 'sip realm is not associated with an account, checking carriers');
const [gw] = await pp.query(sqlSelectCarrierRequiringRegistration, [uri.host, uri.user]);
const matches = gw.filter(gatewayMatchesSourceAddress.bind(null, req.source_address));
const matches = gw.filter(gatewayMatchesSourceAddress.bind(null, logger, req.source_address));
if (1 === matches.length) {
// bingo
//TODO: this assumes the carrier is associate to an account, not an SP
//if the carrier is associated with an SP (which would mean we
//must see a dialed number in the To header, not the register username),
//then we need to look up the account based on the dialed number in the To header
const [a] = await pp.query(sqlAccountBySid, matches[0].account_sid);
const [a] = await pp.query(sqlAccountBySid, [[matches[0].account_sid]]);
if (0 === a.length) return failure;
logger.debug({matches}, `found registration carrier using ${uri.host} and ${uri.user}`);
return {
@@ -212,7 +222,7 @@ module.exports = (srf, logger) => {
/* find all carrier entries that have an inbound gateway matching the source IP */
const [gw] = await pp.query(sqlSelectAllGatewaysForSP);
let matches = gw
.filter(gatewayMatchesSourceAddress.bind(null, req.source_address))
.filter(gatewayMatchesSourceAddress.bind(null, logger, req.source_address))
.map((gw) => {
return {
voip_carrier_sid: gw.voip_carrier_sid,
@@ -247,7 +257,7 @@ module.exports = (srf, logger) => {
}
else if (accountLevelGateways.length === 1) {
const [accounts] = await pp.query('SELECT * from accounts where account_sid = ?',
accountLevelGateways[0].account_sid);
[accountLevelGateways[0].account_sid]);
return {
fromCarrier: true,
gateway: accountLevelGateways[0],
@@ -262,11 +272,11 @@ module.exports = (srf, logger) => {
- way of knowing which account this is for
*/
const [r] = await pp.query('SELECT count(*) as count from accounts where service_provider_sid = ?',
matches[0].service_provider_sid);
[matches[0].service_provider_sid]);
if (r[0].count === 0 || r[0].count > 1) return {fromCarrier: true};
else {
const [accounts] = await pp.query('SELECT * from accounts where service_provider_sid = ?',
matches[0].service_provider_sid);
[matches[0].service_provider_sid]);
return {
fromCarrier: true,
gateway: matches[0],
@@ -288,7 +298,7 @@ module.exports = (srf, logger) => {
/* we have a route for this phone number and carrier combination */
const gateway = matches.find((m) => m.voip_carrier_sid === r[0].voip_carrier_sid);
const [accounts] = await pp.query(sqlAccountBySid, r[0].account_sid);
const [accounts] = await pp.query(sqlAccountBySid, [r[0].account_sid]);
assert(accounts.length);
return {
fromCarrier: true,
+14 -14
View File
@@ -9,12 +9,12 @@
"version": "0.8.3",
"license": "MIT",
"dependencies": {
"@jambonz/db-helpers": "^0.7.9",
"@jambonz/db-helpers": "^0.8.1",
"@jambonz/http-authenticator": "^0.2.2",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/realtimedb-helpers": "^0.7.2",
"@jambonz/rtpengine-utils": "^0.4.3",
"@jambonz/siprec-client-utils": "^0.2.4",
"@jambonz/siprec-client-utils": "^0.2.5",
"@jambonz/stats-collector": "^0.1.8",
"@jambonz/time-series": "^0.2.5",
"aws-sdk": "^2.1354.0",
@@ -595,9 +595,9 @@
}
},
"node_modules/@jambonz/db-helpers": {
"version": "0.7.9",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.7.9.tgz",
"integrity": "sha512-JajIJSPXW0OTjVprDwTH8/yU/qhHY1XkXe6f5PRh0kvRt42AmYggcGKqgivUkY1seR/GVCnQccDcIA2ZEdvDUg==",
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.8.1.tgz",
"integrity": "sha512-pc5TRAYnb89oyD5Ncy9Ik+v/tBqQcNOthbDwaX1OJyGRhPdolgs4YvOTpc0KpSqx7TDjKPS9n5MlqOFWgyDbTA==",
"dependencies": {
"cidr-matcher": "^2.1.1",
"debug": "^4.3.4",
@@ -661,9 +661,9 @@
}
},
"node_modules/@jambonz/siprec-client-utils": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.4.tgz",
"integrity": "sha512-ptwY1crXmYYT0WtkMzxtVyEuH8WD0F4Za3K7YQei3bVMdHS+w2CwndfRWGlectkFTuG/eYhTCPrNzD7oIcRyjg==",
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.5.tgz",
"integrity": "sha512-Ib3M2ecFNxi80gZRG3hcCvxXLLImti1/0bVjAtglGjo1+qn3MyirIVYDchqdabzOC2nWl5aKBEcpG30c2saIDg==",
"dependencies": {
"sdp-transform": "^2.14.1",
"uuid": "^8.3.2"
@@ -5735,9 +5735,9 @@
"dev": true
},
"@jambonz/db-helpers": {
"version": "0.7.9",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.7.9.tgz",
"integrity": "sha512-JajIJSPXW0OTjVprDwTH8/yU/qhHY1XkXe6f5PRh0kvRt42AmYggcGKqgivUkY1seR/GVCnQccDcIA2ZEdvDUg==",
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.8.1.tgz",
"integrity": "sha512-pc5TRAYnb89oyD5Ncy9Ik+v/tBqQcNOthbDwaX1OJyGRhPdolgs4YvOTpc0KpSqx7TDjKPS9n5MlqOFWgyDbTA==",
"requires": {
"cidr-matcher": "^2.1.1",
"debug": "^4.3.4",
@@ -5795,9 +5795,9 @@
}
},
"@jambonz/siprec-client-utils": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.4.tgz",
"integrity": "sha512-ptwY1crXmYYT0WtkMzxtVyEuH8WD0F4Za3K7YQei3bVMdHS+w2CwndfRWGlectkFTuG/eYhTCPrNzD7oIcRyjg==",
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.5.tgz",
"integrity": "sha512-Ib3M2ecFNxi80gZRG3hcCvxXLLImti1/0bVjAtglGjo1+qn3MyirIVYDchqdabzOC2nWl5aKBEcpG30c2saIDg==",
"requires": {
"sdp-transform": "^2.14.1",
"uuid": "^8.3.2"
+2 -2
View File
@@ -25,12 +25,12 @@
"jslint": "eslint app.js lib"
},
"dependencies": {
"@jambonz/db-helpers": "^0.7.9",
"@jambonz/db-helpers": "^0.8.1",
"@jambonz/http-authenticator": "^0.2.2",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/realtimedb-helpers": "^0.7.2",
"@jambonz/rtpengine-utils": "^0.4.3",
"@jambonz/siprec-client-utils": "^0.2.4",
"@jambonz/siprec-client-utils": "^0.2.5",
"@jambonz/stats-collector": "^0.1.8",
"@jambonz/time-series": "^0.2.5",
"aws-sdk": "^2.1354.0",