mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2026-01-24 22:37:51 +00:00
191
lib/db-utils.js
191
lib/db-utils.js
@@ -35,16 +35,6 @@ AND vc.service_provider_sid IS NOT NULL
|
||||
AND vc.is_active = 1
|
||||
AND sg.inbound = 1`;
|
||||
|
||||
const sqlCarriersForAccountBySid =
|
||||
`SELECT sg.sip_gateway_sid, sg.voip_carrier_sid, vc.name, vc.account_sid,
|
||||
vc.application_sid, sg.inbound, sg.outbound, sg.is_active, sg.ipv4, sg.netmask, sg.pad_crypto
|
||||
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 = ? AND is_active = 1';
|
||||
const sqlAccountBySid = 'SELECT * from accounts WHERE account_sid = ?';
|
||||
const sqlApplicationBySid = 'SELECT * from applications WHERE application_sid = ?';
|
||||
@@ -273,115 +263,100 @@ module.exports = (srf, logger) => {
|
||||
/* no match, so fall through */
|
||||
}
|
||||
|
||||
if (isDotDecimal && process.env.JAMBONES_HOSTING) {
|
||||
if (!process.env.SBC_ACCOUNT_SID) return failure;
|
||||
|
||||
/* look for carrier only within that account */
|
||||
const [r] = await pp.query(sqlCarriersForAccountBySid,
|
||||
[process.env.SBC_ACCOUNT_SID, req.source_address, req.source_port]);
|
||||
if (0 === r.length) return failure;
|
||||
const service_provider_sid = await getSPForAccount(process.env.SBC_ACCOUNT_SID);
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway: r[0],
|
||||
account_sid: process.env.SBC_ACCOUNT_SID,
|
||||
service_provider_sid
|
||||
};
|
||||
/* find all carrier entries that have an inbound gateway matching the source IP */
|
||||
const [gw] = await pp.query(sqlSelectAllGatewaysForSP);
|
||||
logger.debug({gw}, `checking gateways for source address ${req.source_address}`);
|
||||
let matches = gw
|
||||
.sort((a, b) => b.netmask - a.netmask)
|
||||
.filter(gatewayMatchesSourceAddress.bind(null, logger, req.source_address))
|
||||
.map((gw) => {
|
||||
return {
|
||||
voip_carrier_sid: gw.voip_carrier_sid,
|
||||
name: gw.name,
|
||||
service_provider_sid: gw.service_provider_sid,
|
||||
account_sid: gw.account_sid,
|
||||
application_sid: gw.application_sid,
|
||||
pad_crypto: gw.pad_crypto
|
||||
};
|
||||
});
|
||||
/* remove duplicates, winnow down to voip_carriers, not gateways */
|
||||
if (matches.length > 1) {
|
||||
matches = [...new Set(matches.map(JSON.stringify))].map(JSON.parse);
|
||||
}
|
||||
else {
|
||||
/* find all carrier entries that have an inbound gateway matching the source IP */
|
||||
const [gw] = await pp.query(sqlSelectAllGatewaysForSP);
|
||||
let matches = gw
|
||||
.sort((a, b) => b.netmask - a.netmask)
|
||||
.filter(gatewayMatchesSourceAddress.bind(null, logger, req.source_address))
|
||||
.map((gw) => {
|
||||
return {
|
||||
voip_carrier_sid: gw.voip_carrier_sid,
|
||||
name: gw.name,
|
||||
service_provider_sid: gw.service_provider_sid,
|
||||
account_sid: gw.account_sid,
|
||||
application_sid: gw.application_sid,
|
||||
pad_crypto: gw.pad_crypto
|
||||
};
|
||||
});
|
||||
/* remove duplicates, winnow down to voip_carriers, not gateways */
|
||||
if (matches.length > 1) {
|
||||
matches = [...new Set(matches.map(JSON.stringify))].map(JSON.parse);
|
||||
}
|
||||
if (matches.length) {
|
||||
/* we have one or more matches. Now check for one with a provisioned phone number matching the DID */
|
||||
const vc_sids = matches.map((m) => `'${m.voip_carrier_sid}'`).join(',');
|
||||
const sql = `SELECT * FROM phone_numbers WHERE number = '${did}' AND voip_carrier_sid IN (${vc_sids})`;
|
||||
logger.debug({matches, sql, did, vc_sids}, 'looking up DID');
|
||||
logger.debug({matches}, `matches for source address ${req.source_address}`);
|
||||
if (matches.length) {
|
||||
/* we have one or more matches. Now check for one with a provisioned phone number matching the DID */
|
||||
const vc_sids = matches.map((m) => `'${m.voip_carrier_sid}'`).join(',');
|
||||
const sql = `SELECT * FROM phone_numbers WHERE number = '${did}' AND voip_carrier_sid IN (${vc_sids})`;
|
||||
logger.debug({matches, sql, did, vc_sids}, 'looking up DID');
|
||||
|
||||
const [r] = await pp.query(sql);
|
||||
if (0 === r.length) {
|
||||
/* came from a provisioned carrier, but the dialed number is not provisioned.
|
||||
check if we have an account with default routing of that carrier to an application
|
||||
*/
|
||||
const accountLevelGateways = matches.filter((m) => m.account_sid && m.application_sid);
|
||||
if (accountLevelGateways.length > 1) {
|
||||
logger.info({accounts: accountLevelGateways.map((m) => m.account_sid)},
|
||||
'multiple accounts have added this carrier with default routing -- cannot determine which to use');
|
||||
return {
|
||||
fromCarrier: true,
|
||||
error: 'Multiple accounts are attempting to default route this carrier'
|
||||
};
|
||||
}
|
||||
else if (accountLevelGateways.length === 1) {
|
||||
const [accounts] = await pp.query('SELECT * from accounts where account_sid = ?',
|
||||
[accountLevelGateways[0].account_sid]);
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway: accountLevelGateways[0],
|
||||
service_provider_sid: accountLevelGateways[0].service_provider_sid,
|
||||
account_sid: accountLevelGateways[0].account_sid,
|
||||
application_sid: accountLevelGateways[0].application_sid,
|
||||
account: accounts[0]
|
||||
};
|
||||
}
|
||||
else {
|
||||
/* check if we only have a single account, otherwise we have no
|
||||
- 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]);
|
||||
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]);
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway: matches[0],
|
||||
service_provider_sid: accounts[0].service_provider_sid,
|
||||
account_sid: accounts[0].account_sid,
|
||||
account: accounts[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r.length > 1) {
|
||||
logger.info({r},
|
||||
const [r] = await pp.query(sql);
|
||||
if (0 === r.length) {
|
||||
/* came from a provisioned carrier, but the dialed number is not provisioned.
|
||||
check if we have an account with default routing of that carrier to an application
|
||||
*/
|
||||
const accountLevelGateways = matches.filter((m) => m.account_sid && m.application_sid);
|
||||
if (accountLevelGateways.length > 1) {
|
||||
logger.info({accounts: accountLevelGateways.map((m) => m.account_sid)},
|
||||
'multiple accounts have added this carrier with default routing -- cannot determine which to use');
|
||||
return {
|
||||
fromCarrier: true,
|
||||
error: 'Multiple accounts are attempting to route the same phone number from the same carrier'
|
||||
error: 'Multiple accounts are attempting to default route this carrier'
|
||||
};
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
assert(accounts.length);
|
||||
else if (accountLevelGateways.length === 1) {
|
||||
const [accounts] = await pp.query('SELECT * from accounts where account_sid = ?',
|
||||
[accountLevelGateways[0].account_sid]);
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway: accountLevelGateways[0],
|
||||
service_provider_sid: accountLevelGateways[0].service_provider_sid,
|
||||
account_sid: accountLevelGateways[0].account_sid,
|
||||
application_sid: accountLevelGateways[0].application_sid,
|
||||
account: accounts[0]
|
||||
};
|
||||
}
|
||||
else {
|
||||
/* check if we only have a single account, otherwise we have no
|
||||
- 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]);
|
||||
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]);
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway: matches[0],
|
||||
service_provider_sid: accounts[0].service_provider_sid,
|
||||
account_sid: accounts[0].account_sid,
|
||||
account: accounts[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r.length > 1) {
|
||||
logger.info({r},
|
||||
'multiple accounts have added this carrier with default routing -- cannot determine which to use');
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway,
|
||||
service_provider_sid: accounts[0].service_provider_sid,
|
||||
account_sid: r[0].account_sid,
|
||||
application_sid: r[0].application_sid,
|
||||
account: accounts[0]
|
||||
error: 'Multiple accounts are attempting to route the same phone number from the same carrier'
|
||||
};
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
assert(accounts.length);
|
||||
return {
|
||||
fromCarrier: true,
|
||||
gateway,
|
||||
service_provider_sid: accounts[0].service_provider_sid,
|
||||
account_sid: r[0].account_sid,
|
||||
application_sid: r[0].application_sid,
|
||||
account: accounts[0]
|
||||
};
|
||||
}
|
||||
return failure;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,8 @@ values ('f4e1848d-3ff8-40eb-b9c1-30e1ef053f94','ed649e33-e771-403a-8c99-1780eabb
|
||||
insert into account_products(account_product_sid, account_subscription_sid, product_sid,quantity)
|
||||
values ('f23ff996-6534-4aba-8666-4b347391eca2', 'f4e1848d-3ff8-40eb-b9c1-30e1ef053f94', 'c4403cdb-8e75-4b27-9726-7d8315e3216d', 10);
|
||||
|
||||
insert into voip_carriers (voip_carrier_sid, name, account_sid) values ('287c1452-620d-4195-9f19-c9814ef90d78', 'westco', 'ed649e33-e771-403a-8c99-1780eabbc803');
|
||||
insert into voip_carriers (voip_carrier_sid, name, account_sid, service_provider_sid)
|
||||
values ('287c1452-620d-4195-9f19-c9814ef90d78', 'westco', 'ed649e33-e771-403a-8c99-1780eabbc803', '3f35518f-5a0d-4c2e-90a5-2407bb3b36f0');
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, inbound, outbound)
|
||||
values ('124a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.38.0.20', true, true);
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound)
|
||||
@@ -42,7 +43,8 @@ insert into account_products(account_product_sid, account_subscription_sid, prod
|
||||
values ('92f137f7-4bc3-4157-b096-6817e54b1874', '73bbcc5d-512f-4cea-8535-9a6e3d2bd19d', 'c4403cdb-8e75-4b27-9726-7d8315e3216d', 0);
|
||||
insert into account_limits(account_limits_sid, account_sid, category, quantity) values('a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d', 'd7cc37cb-d152-49ef-a51b-485f6e917089', 'voice_call_session', 0);
|
||||
|
||||
insert into voip_carriers (voip_carrier_sid, name, account_sid) values ('9b1abdc7-0220-4964-bc66-32b5c70cd9ab', 'westco', 'd7cc37cb-d152-49ef-a51b-485f6e917089');
|
||||
insert into voip_carriers (voip_carrier_sid, name, account_sid, service_provider_sid)
|
||||
values ('9b1abdc7-0220-4964-bc66-32b5c70cd9ab', 'westco', 'd7cc37cb-d152-49ef-a51b-485f6e917089', '3f35518f-5a0d-4c2e-90a5-2407bb3b36f0');
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, inbound, outbound)
|
||||
values ('12f401d9-cbb1-49e5-bd33-cefbca0badc3', '9b1abdc7-0220-4964-bc66-32b5c70cd9ab', '172.38.0.20', true, true);
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound)
|
||||
@@ -52,7 +54,8 @@ values ('1401eb72-0daf-4471-aba6-038a0a2587b3', '9b1abdc7-0220-4964-bc66-32b5c70
|
||||
insert into applications (application_sid, name, account_sid, call_hook_sid, call_status_hook_sid)
|
||||
values ('3b43e39f-4346-4218-8434-a53130e8be49', 'test', 'ee9d7d49-b3e4-4fdb-9d66-661149f717e8', '90dda62e-0ea2-47d1-8164-5bd49003476c', '4d7ce0aa-5ead-4e61-9a6b-3daa732218b1');
|
||||
|
||||
insert into voip_carriers (voip_carrier_sid, name, account_sid, application_sid) values ('999c1452-620d-4195-9f19-c9814ef90d78', 'customer PBX', 'ee9d7d49-b3e4-4fdb-9d66-661149f717e8', '3b43e39f-4346-4218-8434-a53130e8be49');
|
||||
insert into voip_carriers (voip_carrier_sid, name, account_sid, application_sid, service_provider_sid)
|
||||
values ('999c1452-620d-4195-9f19-c9814ef90d78', 'customer PBX', 'ee9d7d49-b3e4-4fdb-9d66-661149f717e8', '3b43e39f-4346-4218-8434-a53130e8be49', '3f35518f-5a0d-4c2e-90a5-2407bb3b36f0');
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, inbound, outbound)
|
||||
values ('888a5339-c62c-4075-9e19-f4de70a96597', '999c1452-620d-4195-9f19-c9814ef90d78', '172.38.0.21', true, false);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
INVITE sip:16173333456@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>
|
||||
@@ -33,7 +33,7 @@
|
||||
CSeq: 1 INVITE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Subject: uac-no-3pcc
|
||||
Content-Type: application/sdp
|
||||
Content-Length: 0
|
||||
|
||||
@@ -49,13 +49,13 @@
|
||||
<send>
|
||||
<![CDATA[
|
||||
|
||||
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
ACK sip:16173333456@[remote_ip]:[remote_port] SIP/2.0
|
||||
[last_Via]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]
|
||||
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 ACK
|
||||
Subject: uac-device-unknown-user
|
||||
Subject: uac-no-3pcc
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
|
||||
@@ -34,7 +34,7 @@ test('incoming call tests', async(t) => {
|
||||
obj = await getJSON('http://127.0.0.1:3050/system-health');
|
||||
t.ok(obj.calls === 0, 'HTTP GET /system-health works (health check)')
|
||||
|
||||
await sippUac('uac-late-media.xml', '172.38.0.30');
|
||||
await sippUac('uac-late-media.xml', '172.38.0.20');
|
||||
t.pass('incoming call with no SDP packet is rejected with a 488');
|
||||
|
||||
await sippUac('uac-pcap-carrier-success.xml', '172.38.0.20');
|
||||
@@ -72,7 +72,7 @@ test('incoming call tests', async(t) => {
|
||||
await waitFor(12);
|
||||
const res = await queryCdrs({account_sid: 'ed649e33-e771-403a-8c99-1780eabbc803'});
|
||||
//console.log(`cdrs: ${JSON.stringify(res)}`);
|
||||
t.ok(8 === res.total, 'successfully wrote 8 cdrs for calls');
|
||||
t.ok(7 === res.total, 'successfully wrote 8 cdrs for calls');
|
||||
|
||||
srf.disconnect();
|
||||
t.end();
|
||||
|
||||
Reference in New Issue
Block a user