Skip to content

Commit 2211aee

Browse files
committed
wip
1 parent 5e214b6 commit 2211aee

File tree

10 files changed

+81
-24
lines changed

10 files changed

+81
-24
lines changed

app.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ const {
8585
removeFromSet,
8686
isMemberOfSet,
8787
retrieveSet,
88-
createHash
8988
} = require('@jambonz/realtimedb-helpers')({}, logger);
9089

9190
const interval = SBC_PUBLIC_ADDRESS_KEEP_ALIVE_IN_MILISECOND || 900000; // Default 15 minutes
@@ -117,7 +116,6 @@ srf.locals = {
117116
addKeyNx,
118117
retrieveKey,
119118
retrieveSet,
120-
createHash
121119
},
122120
writeAlerts,
123121
AlertType

lib/regbot.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66
REGISTER_RESPONSE_REMOVE,
77
JAMBONES_REGBOT_USER_AGENT
88
} = require('./config');
9-
const {isValidDomainOrIP} = require('./utils');
9+
const {isValidDomainOrIP, createEphemeralGateway} = require('./utils');
1010
const DEFAULT_EXPIRES = (parseInt(JAMBONES_REGBOT_DEFAULT_EXPIRES_INTERVAL) || 3600);
1111
const MIN_EXPIRES = (parseInt(JAMBONES_REGBOT_MIN_EXPIRES_INTERVAL) || 30);
1212
const assert = require('assert');
@@ -69,8 +69,8 @@ class Regbot {
6969
}
7070

7171
async register(srf) {
72+
const { client } = srf.locals.realtimeDbHelpers;
7273
const { updateVoipCarriersRegisterStatus } = srf.locals.dbHelpers;
73-
const { createHash } = srf.locals.realtimeDbHelpers;
7474
const { writeAlerts, localSIPDomain } = srf.locals;
7575
try {
7676
// transport
@@ -207,7 +207,7 @@ class Regbot {
207207
if (addresses.length) {
208208
try {
209209
await Promise.all(
210-
addresses.map((ip) => createHash(`reg-gateway:${ip}`, this.voip_carrier_sid, expires))
210+
addresses.map((ip) => createEphemeralGateway(client, this.logger, ip, this.voip_carrier_sid, expires))
211211
);
212212
} catch (err) {
213213
this.logger.error({addresses, err}, 'Error creating hash for reg-gateway');

lib/sip-trunk-register.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const regbots = [];
1818
const carriers = [];
1919
const gateways = [];
2020

21+
const getCountSuccessfulRegbots = () => regbots.filter((rb) => rb.status === 'registered').length;
2122

2223
function pickRelevantCarrierProperties(c) {
2324
return {
@@ -92,6 +93,14 @@ module.exports = async(logger, srf) => {
9293
active: false
9394
};
9495

96+
srf.locals.regbotStatus = () => {
97+
return {
98+
total: regbots.length,
99+
registered: getCountSuccessfulRegbots(),
100+
active: srf.locals.regbot.active
101+
};
102+
};
103+
95104
/* Set the Local SIP domain on srf.locals */
96105
await getLocalSIPDomain(logger, srf); // Initial Setup
97106
setInterval(getLocalSIPDomain, 300000, logger, srf); //Refresh SIP Domain every 5 mins
@@ -211,10 +220,12 @@ const updateCarrierRegbots = async(logger, srf) => {
211220
}
212221
if (JSON.stringify(gws) !== JSON.stringify(gateways)) hasChanged = true;
213222

223+
//logger.info({ hasChanged, new: gws, old: gateways }, 'updateCarrierRegbots: checked for changes');
224+
214225
if (hasChanged) {
215226

216227
debug('updateCarrierRegbots: got new or changed carriers');
217-
logger.info('updateCarrierRegbots: got new or changed carriers');
228+
logger.info({gws}, 'updateCarrierRegbots: got new or changed carriers');
218229
carriers.length = 0;
219230
Array.prototype.push.apply(carriers, cs);
220231

lib/utils.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,31 @@ function isValidDomainOrIP(input) {
7272

7373
const sleepFor = async(ms) => new Promise((resolve) => setTimeout(resolve, ms));
7474

75+
const createEphemeralGateway = (client, logger, ipAddress, voipCarrierSid, ttlSeconds) => {
76+
77+
const key = `eph-gw-ip:${ipAddress}`;
78+
const expiryTimestamp = Math.floor(Date.now() / 1000) + ttlSeconds;
79+
80+
const multi = client.multi();
81+
82+
// Use HSET (not HSETNX) to allow updates
83+
multi.hset(key, voipCarrierSid, expiryTimestamp);
84+
85+
// Optional: Set conservative key expiry
86+
multi.expire(key, 7200);
87+
88+
return new Promise((resolve, reject) => {
89+
multi.exec((err, results) => {
90+
if (err) {
91+
logger.error({err}, `createEphemeralGateway: error for ${key}`);
92+
return reject(err);
93+
}
94+
logger.debug({voipCarrierSid, ipAddress, ttlSeconds}, `createEphemeralGateway: created ${key}`);
95+
resolve(true);
96+
});
97+
});
98+
};
99+
75100
module.exports = {
76101
isUacBehindNat,
77102
getSipProtocol,
@@ -81,5 +106,6 @@ module.exports = {
81106
NAT_EXPIRES: 30,
82107
isValidIPv4,
83108
isValidDomainOrIP,
84-
sleepFor
109+
sleepFor,
110+
createEphemeralGateway
85111
};

test/db/jambones-sql.sql

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* SQLEditor (MySQL (2))*/
2-
32
SET FOREIGN_KEY_CHECKS=0;
43

54
DROP TABLE IF EXISTS account_static_ips;
@@ -351,14 +350,18 @@ speech_credential_sid CHAR(36) NOT NULL,
351350
model VARCHAR(512) NOT NULL,
352351
reported_usage ENUM('REPORTED_USAGE_UNSPECIFIED','REALTIME','OFFLINE') DEFAULT 'REALTIME',
353352
name VARCHAR(64) NOT NULL,
353+
voice_cloning_key MEDIUMTEXT,
354+
use_voice_cloning_key BOOLEAN DEFAULT false,
354355
PRIMARY KEY (google_custom_voice_sid)
355356
);
356357

357358
CREATE TABLE system_information
358359
(
359360
domain_name VARCHAR(255),
360361
sip_domain_name VARCHAR(255),
361-
monitoring_domain_name VARCHAR(255)
362+
monitoring_domain_name VARCHAR(255),
363+
private_network_cidr VARCHAR(8192),
364+
log_level ENUM('info', 'debug') NOT NULL DEFAULT 'info'
362365
);
363366

364367
CREATE TABLE users
@@ -412,6 +415,9 @@ register_from_user VARCHAR(128),
412415
register_from_domain VARCHAR(255),
413416
register_public_ip_in_contact BOOLEAN NOT NULL DEFAULT false,
414417
register_status VARCHAR(4096),
418+
dtmf_type ENUM('rfc2833','tones','info') NOT NULL DEFAULT 'rfc2833',
419+
outbound_sip_proxy VARCHAR(255),
420+
trunk_type ENUM('static_ip','auth','reg') NOT NULL DEFAULT 'static_ip',
415421
PRIMARY KEY (voip_carrier_sid)
416422
) COMMENT='A Carrier or customer PBX that can send or receive calls';
417423

@@ -497,7 +503,7 @@ messaging_hook_sid CHAR(36) COMMENT 'webhook to call for inbound SMS/MMS ',
497503
app_json TEXT,
498504
speech_synthesis_vendor VARCHAR(64) NOT NULL DEFAULT 'google',
499505
speech_synthesis_language VARCHAR(12) NOT NULL DEFAULT 'en-US',
500-
speech_synthesis_voice VARCHAR(256),
506+
speech_synthesis_voice VARCHAR(256) DEFAULT 'en-US-Standard-C',
501507
speech_synthesis_label VARCHAR(64),
502508
speech_recognizer_vendor VARCHAR(64) NOT NULL DEFAULT 'google',
503509
speech_recognizer_language VARCHAR(64) NOT NULL DEFAULT 'en-US',
@@ -510,6 +516,7 @@ fallback_speech_synthesis_label VARCHAR(64),
510516
fallback_speech_recognizer_vendor VARCHAR(64),
511517
fallback_speech_recognizer_language VARCHAR(64),
512518
fallback_speech_recognizer_label VARCHAR(64),
519+
env_vars TEXT,
513520
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
514521
record_all_calls BOOLEAN NOT NULL DEFAULT false,
515522
PRIMARY KEY (application_sid)
@@ -552,6 +559,7 @@ siprec_hook_sid CHAR(36),
552559
record_all_calls BOOLEAN NOT NULL DEFAULT false,
553560
record_format VARCHAR(16) NOT NULL DEFAULT 'mp3',
554561
bucket_credential VARCHAR(8192) COMMENT 'credential used to authenticate with storage service',
562+
enable_debug_log BOOLEAN NOT NULL DEFAULT false,
555563
PRIMARY KEY (account_sid)
556564
) COMMENT='An enterprise that uses the platform for comm services';
557565

@@ -736,4 +744,4 @@ ALTER TABLE accounts ADD FOREIGN KEY device_calling_application_sid_idxfk (devic
736744

737745
ALTER TABLE accounts ADD FOREIGN KEY siprec_hook_sid_idxfk (siprec_hook_sid) REFERENCES applications (application_sid);
738746

739-
SET FOREIGN_KEY_CHECKS=1;
747+
SET FOREIGN_KEY_CHECKS=1;

test/db/populate-test-data2.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
insert into voip_carriers (voip_carrier_sid, name, e164_leading_plus, requires_register, register_username, register_sip_realm, register_password, register_from_user, register_from_domain, register_public_ip_in_contact)
22
values ('287c1452-620d-4195-9f19-c9814ef90d78', 'westco', 1, 1, 'foo', 'sip.jambonz.org', 'bar', 'reguser', 'regdomain', 0);
3-
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, inbound, outbound, send_options_ping)
4-
values ('124a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.39.0.14', true, true, true);
3+
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound, send_options_ping)
4+
values ('124a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.39.0.14', 5060, true, true, true);

test/db/populate-test-data3.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, inbound, outbound)
2-
values ('987a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.39.0.15', false, true);
1+
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound)
2+
values ('987a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.39.0.15', 5060, false, true);

test/db/populate-test-data4.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
delete from sip_gateways;
2+
delete from voip_carriers;
3+
insert into voip_carriers (voip_carrier_sid, name, e164_leading_plus, requires_register, register_username, register_sip_realm, register_password, register_from_user, register_public_ip_in_contact, trunk_type)
4+
values ('287c1452-620d-4195-9f19-c9814ef90d78', 'westco', 1, 1, 'daveh', 'beachdog.sip.jambonz.cloud', 'foobarbazzle', 'daveh', 0, 'reg');
5+
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound, send_options_ping)
6+
values ('124a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', 'beachdog.sip.jambonz.cloud', 5060, false, true, false);

test/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require('./docker_start');
22
require('./create-test-db');
3-
// require('./regbot-tests');
3+
require('./regbot-tests');
44
require('./regbot-unit-test');
55
require('./sip-register-tests');
66
require('./sip-options-tests');

test/regbot-tests.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ test('populating more test case data', (t) => {
4848
test('trunk register tests', (t) => {
4949
clearModule.all();
5050
const { srf } = require('../app');
51-
t.timeoutAfter(60000);
51+
t.timeoutAfter(180000);
5252

53+
console.log('waiting 15 seconds for regbot to start up');
5354
connect(srf)
54-
.then(wait.bind(null, 1500))
55+
.then(wait.bind(null, 15000))
5556
.then(() => {
5657
const obj = srf.locals.regbotStatus();
5758
return t.ok(obj.total === 1 && obj.registered === 1, 'initial regbot running and successfully registered to trunk');
@@ -66,21 +67,27 @@ test('trunk register tests', (t) => {
6667
});
6768
})
6869
.then(() => {
69-
return wait(35000);
70+
console.log('waiting 65 seconds for regbot to come around to check for new gateways');
71+
return wait(65000);
7072
})
7173
.then(() => {
7274
const obj = srf.locals.regbotStatus();
75+
//console.log({obj}, 'regbot status after adding new gateway');
7376
return t.ok(obj.total === 2 && obj.registered === 1, 'successfully added gateway that tests failure result');
7477
})
7578
.then(() => {
7679
return new Promise((resolve, reject) => {
77-
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp -D jambones_test -e "delete from sip_gateways where sip_gateway_sid = '987a5339-c62c-4075-9e19-f4de70a96597'"`, (err, stdout, stderr) => {
80+
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp -D jambones_test < ${__dirname}/db/populate-test-data4.sql`, (err, stdout, stderr) => {
7881
if (err) return reject(err);
79-
t.pass('added new gateway');
82+
t.pass('added new reg trunk');
8083
resolve();
8184
});
8285
});
8386
})
87+
.then(() => {
88+
console.log('waiting 65 seconds for regbot to come around to check for new reg trunk');
89+
return wait(65000);
90+
})
8491
.then(() => {
8592
if (srf.locals.lb) srf.locals.lb.disconnect();
8693
srf.disconnect();
@@ -96,10 +103,11 @@ test('trunk register tests', (t) => {
96103
});
97104
});
98105

106+
/*
99107
test('trunk register tests when its IP in redis cache', (t) => {
100108
clearModule.all();
101109
const { srf } = require('../app');
102-
t.timeoutAfter(60000);
110+
t.timeoutAfter(90000);
103111
addToSet(setName, "172.39.0.10:5060");
104112
105113
connect(srf)
@@ -125,7 +133,6 @@ test('trunk register tests when its IP in redis cache', (t) => {
125133
});
126134
});
127135
128-
129136
test('trunk register with sbc public IP address', (t) => {
130137
clearModule.all();
131138
const { srf } = require('../app');
@@ -195,4 +202,5 @@ test('trunk not register tests when its IP is not in redis cache', (t) => {
195202
console.log(`error received: ${err}`);
196203
t.error(err);
197204
});
198-
});
205+
});
206+
*/

0 commit comments

Comments
 (0)