Compare commits

...
25 Commits
Author SHA1 Message Date
Dave Horton 98ecfa20aa add support for redis auth 2022-03-08 09:30:44 -05:00
Dave Horton 56efe50aec forward incoming REFER to FS (#34) 2022-03-05 15:21:49 -05:00
Dave Horton 891d0ff38b use registered contact as uri when sending to user (#32) 2022-02-23 15:09:18 -05:00
Dave Horton 78d6cb5f22 use registered contact as uri when sending to user (#31) 2022-02-17 21:35:19 -05:00
Dave Horton 23255a71db added pre-commit hook for linting 2022-02-14 13:18:46 -05:00
Dave Horton 4cb34ad784 regression handling 302 redirect 2022-02-14 12:11:32 -05:00
Dave Horton f096a31a95 bump version 2022-02-09 15:43:50 -05:00
Dave Horton f671ef56bb update to latest @jambonz/realtimedb-helpers with support for redis username / password auth 2022-02-09 15:16:03 -05:00
Dave Horton 3a2fcf5976 update deps 2022-02-09 08:24:43 -05:00
Dave Horton dd85ec762d merge support for X-Override-To feature back into main branch 2022-02-01 12:30:34 -05:00
Dave Horton 61ec935ab8 0.7.2 version 2022-01-28 09:13:25 -05:00
Snyk bot cd7c425f7e fix: Dockerfile to reduce vulnerabilities (#30)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-2340908
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-2340908
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-2340922
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-2340922
2022-01-28 08:03:40 -05:00
Dave Horton e9b8cd595a Feature/rtpengine locate by dns (#29)
* k8s: query dns for rtpengine endpoints

* use udp now in k8s

* catch error on rtpengine failure

* specify node version in gh actions
2022-01-23 18:04:15 -05:00
Dave Horton fc7cdae22a Feature/rtpengine locate by dns (#28)
* k8s: query dns for rtpengine endpoints

* use udp now in k8s

* catch error on rtpengine failure
2022-01-23 17:32:51 -05:00
Dave Horton 2ca44c4f5a healthcheck only in k8s 2022-01-22 21:43:18 -05:00
Dave Horton 50ff35c582 update to rtpengine-utils that reconnects ws 2022-01-19 19:25:47 -05:00
Dave Horton a318b07f61 Merge branch 'main' of github.com:jambonz/sbc-outbound into main 2022-01-17 18:40:07 -05:00
Dave Horton be354cde10 avoid adding multiple reset flags to rtpengine params 2022-01-17 18:39:51 -05:00
Snyk bot 594e8983e8 fix: Dockerfile to reduce vulnerabilities (#27)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
- https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
- https://snyk.io/vuln/SNYK-DEBIAN11-GMP-1920938
- https://snyk.io/vuln/SNYK-DEBIAN11-LIBGCRYPT20-1297892
- https://snyk.io/vuln/SNYK-DEBIAN11-PERL-1925976
2022-01-17 07:50:37 -05:00
Dave Horton 13f7d583df use ws rather than tcp for rtpengine connection in K8S 2022-01-12 08:28:59 -05:00
Dave Horton 6085452469 add support for tcp connections to rtpengine (#26) 2022-01-11 15:46:52 -05:00
Dave Horton 64ac043656 add support for using ws to connect to rtpengine 2022-01-10 22:01:41 -05:00
Dave Horton 7e9d48ee5b JAMBONES_NETWORK_CIDR not needed for K8S (#25) 2022-01-09 14:59:44 -05:00
Dave Horton fa7de71650 support for routing based on X-Jambonz-Routing header 2022-01-08 13:01:02 -05:00
Dave Horton 9d228d4805 K8s changes (#24)
* support multiple CIDRs

* use outbound in k8s

* k8s: user service for rtpengine

* bugfix: drachtio connection was dropped after successful connect

* Dockerfile

* k8s pre-stop hook

* make hjook executable

* update deps
2022-01-06 12:37:04 -05:00
22 changed files with 3135 additions and 370 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
node-version: 14.x
- run: npm ci
- run: npm run jslint
- run: npm test
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run jslint
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:16
FROM node:17.4-slim
WORKDIR /opt/app/
COPY package.json ./
RUN npm install
+64 -24
View File
@@ -6,12 +6,12 @@ assert.ok(process.env.JAMBONES_MYSQL_HOST &&
assert.ok(process.env.JAMBONES_REDIS_HOST, 'missing JAMBONES_REDIS_HOST env var');
assert.ok(process.env.DRACHTIO_PORT || process.env.DRACHTIO_HOST, 'missing DRACHTIO_PORT env var');
assert.ok(process.env.DRACHTIO_SECRET, 'missing DRACHTIO_SECRET env var');
assert.ok(process.env.JAMBONES_NETWORK_CIDR, 'missing JAMBONES_NETWORK_CIDR env var');
assert.ok(process.env.JAMBONES_NETWORK_CIDR || process.env.K8S, 'missing JAMBONES_NETWORK_CIDR env var');
const Srf = require('drachtio-srf');
const srf = new Srf('sbc-outbound');
const CIDRMatcher = require('cidr-matcher');
const matcher = new CIDRMatcher([process.env.JAMBONES_NETWORK_CIDR]);
const {pingMsTeamsGateways, equalsIgnoreOrder} = require('./lib/utils');
const opts = Object.assign({
timestamp: () => {return `, "time": "${new Date().toISOString()}"`;}
}, {level: process.env.JAMBONES_LOGLEVEL || 'info'});
@@ -46,7 +46,14 @@ const {
database: process.env.JAMBONES_MYSQL_DATABASE,
connectionLimit: process.env.JAMBONES_MYSQL_CONNECTION_LIMIT || 10
}, logger);
const {createHash, retrieveHash, incrKey, decrKey, retrieveSet} = require('@jambonz/realtimedb-helpers')({
const {
createHash,
retrieveHash,
incrKey,
decrKey,
retrieveSet,
isMemberOfSet
} = require('@jambonz/realtimedb-helpers')({
host: process.env.JAMBONES_REDIS_HOST || 'localhost',
port: process.env.JAMBONES_REDIS_PORT || 6379
}, logger);
@@ -73,7 +80,8 @@ srf.locals = {...srf.locals,
createHash,
retrieveHash,
incrKey,
decrKey
decrKey,
isMemberOfSet
}
};
const {initLocals, checkLimits, route} = require('./lib/middleware')(srf, logger, {
@@ -82,11 +90,18 @@ const {initLocals, checkLimits, route} = require('./lib/middleware')(srf, logger
});
const {getRtpEngine, setRtpEngines} = require('@jambonz/rtpengine-utils')([], logger, {
emitter: stats,
dtmfListenPort: process.env.DTMF_LISTEN_PORT || 22225
dtmfListenPort: process.env.DTMF_LISTEN_PORT || 22225,
protocol: 'udp'
});
srf.locals.getRtpEngine = getRtpEngine;
if (process.env.DRACHTIO_HOST) {
if (process.env.DRACHTIO_HOST && !process.env.K8S) {
const cidrs = process.env.JAMBONES_NETWORK_CIDR
.split(',')
.map((s) => s.trim());
logger.info({cidrs}, 'internal network CIDRs');
const matcher = new CIDRMatcher(cidrs);
srf.connect({host: process.env.DRACHTIO_HOST, port: process.env.DRACHTIO_PORT, secret: process.env.DRACHTIO_SECRET });
srf.on('connect', (err, hp) => {
logger.info(`connected to drachtio listening on ${hp}`);
@@ -107,6 +122,7 @@ if (process.env.DRACHTIO_HOST) {
});
}
else {
logger.info(`listening in outbound mode on port ${process.env.DRACHTIO_PORT}`);
srf.listen({port: process.env.DRACHTIO_PORT, secret: process.env.DRACHTIO_SECRET});
}
if (process.env.NODE_ENV === 'test') {
@@ -121,33 +137,59 @@ srf.invite((req, res) => {
session.connect();
});
/* update call stats periodically */
setInterval(() => {
stats.gauge('sbc.sip.calls.count', activeCallIds.size, ['direction:outbound']);
}, 5000);
if (process.env.K8S) {
const PORT = process.env.HTTP_PORT || 3000;
const getCount = () => activeCallIds.size;
const healthCheck = require('@jambonz/http-health-check');
healthCheck({port: PORT, logger, path: '/', fn: getCount});
}
const arrayCompare = (a, b) => {
if (a.length !== b.length) return false;
const uniqueValues = new Set([...a, ...b]);
for (const v of uniqueValues) {
const aCount = a.filter((e) => e === v).length;
const bCount = b.filter((e) => e === v).length;
if (aCount !== bCount) return false;
}
return true;
if ('test' !== process.env.NODE_ENV) {
/* update call stats periodically */
setInterval(() => {
stats.gauge('sbc.sip.calls.count', activeCallIds.size, ['direction:outbound']);
}, 5000);
}
const lookupRtpServiceEndpoints = (lookup, serviceName) => {
logger.debug(`dns lookup for ${serviceName}..`);
lookup(serviceName, {family: 4, all: true}, (err, addresses) => {
if (err) {
logger.error({err}, `Error looking up ${serviceName}`);
return;
}
logger.debug({addresses, rtpServers}, `dns lookup for ${serviceName} returned`);
const addrs = addresses.map((a) => a.address);
if (!equalsIgnoreOrder(addrs, rtpServers)) {
rtpServers.length = 0;
Array.prototype.push.apply(rtpServers, addrs);
logger.info({rtpServers}, 'rtpserver endpoints have been updated');
setRtpEngines(rtpServers.map((a) => `${a}:${process.env.RTPENGINE_PORT || 22222}`));
}
});
};
/* update rtpengines periodically */
if (process.env.JAMBONES_RTPENGINES) {
if (process.env.K8S_RTPENGINE_SERVICE_NAME) {
/* poll dns for endpoints every so often */
const arr = /^(.*):(\d+)$/.exec(process.env.K8S_RTPENGINE_SERVICE_NAME);
const svc = arr[1];
logger.info(`rtpengine(s) will be found at dns name: ${svc}`);
const {lookup} = require('dns');
lookupRtpServiceEndpoints(lookup, svc);
setInterval(lookupRtpServiceEndpoints.bind(null, lookup, svc), process.env.RTPENGINE_DNS_POLL_INTERVAL || 10000);
}
else if (process.env.JAMBONES_RTPENGINES) {
/* static list of rtpengines */
setRtpEngines([process.env.JAMBONES_RTPENGINES]);
}
else {
/* poll redis periodically for rtpengines that have registered via OPTIONS ping */
const getActiveRtpServers = async() => {
try {
const set = await retrieveSet(setNameRtp);
const newArray = Array.from(set);
logger.debug({newArray, rtpServers}, 'getActiveRtpServers');
if (!arrayCompare(newArray, rtpServers)) {
if (!equalsIgnoreOrder(newArray, rtpServers)) {
logger.info({newArray}, 'resetting active rtpengines');
setRtpEngines(newArray.map((a) => `${a}:${process.env.RTPENGINE_PORT || 22222}`));
rtpServers.length = 0;
@@ -157,14 +199,12 @@ else {
logger.error({err}, 'Error setting new rtpengines');
}
};
setInterval(() => {
getActiveRtpServers();
}, 30000);
getActiveRtpServers();
}
const {pingMsTeamsGateways} = require('./lib/utils');
pingMsTeamsGateways(logger, srf);
module.exports = {srf};
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env node
const bent = require('bent');
const getJSON = bent('json');
const PORT = process.env.HTTP_PORT || 3000;
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
(async function() {
try {
do {
const obj = await getJSON(`http://127.0.0.1:${PORT}/`);
const {calls} = obj;
if (calls === 0) {
console.log('no calls on the system, we can exit');
process.exit(0);
}
else {
console.log(`waiting for ${calls} to exit..`);
}
await sleep(10000);
} while (1);
} catch (err) {
console.error(err, 'Error querying health endpoint');
process.exit(-1);
}
})();
+57 -12
View File
@@ -124,14 +124,19 @@ class CallSession extends Emitter {
};
if (this.req.locals.registration) {
debug(`sending call to user ${JSON.stringify(this.req.locals.registration)}`);
debug(`sending call to registered user ${JSON.stringify(this.req.locals.registration)}`);
const contact = this.req.locals.registration.contact;
if (contact.includes('transport=ws')) {
uris = [contact];
let destUri = contact;
if (this.req.has('X-Override-To')) {
const dest = this.req.get('X-Override-To');
const uri = parseUri(contact);
uri.user = dest;
destUri = stringifyUri(uri);
this.logger.info(`overriding destination user with ${dest}, so final uri is ${destUri}`);
}
else {
uris = [destUri];
if (!contact.includes('transport=ws')) {
proxy = this.req.locals.registration.proxy;
uris = [this.req.uri];
}
}
else if (this.req.locals.target === 'forward') {
@@ -208,7 +213,8 @@ class CallSession extends Emitter {
} catch (err) {
debug(err);
this.logger.error(err, 'Error performing lcr');
return this.res.send(488);
this.res.send(488);
return this.srf.endSession(this.req);
}
debug(`sending call to PSTN ${uris}`);
}
@@ -276,9 +282,23 @@ class CallSession extends Emitter {
const {uas, uac} = await this.srf.createB2BUA(this.req, this.res, uri, {
proxy,
passFailure,
proxyRequestHeaders: ['all', '-X-MS-Teams-FQDN', '-X-MS-Teams-Tenant-FQDN', 'X-CID', '-Allow',
'-Session-Expires', '-X-Requested-Carrier-Sid', 'Min-SE'],
proxyResponseHeaders: ['all', '-Allow', '-Session-Expires'],
proxyRequestHeaders: [
'all',
'-X-MS-Teams-FQDN',
'-X-MS-Teams-Tenant-FQDN',
'X-CID',
'-Allow',
'-Session-Expires',
'-X-Requested-Carrier-Sid',
'-X-Jambonz-Routing',
'-X-Jambonz-FS-UUID',
'Min-SE'
],
proxyResponseHeaders: [
'all',
'-Allow',
'-Session-Expires'
],
headers: hdrs,
responseHeaders,
auth: gw ? gw.auth : undefined,
@@ -357,7 +377,8 @@ class CallSession extends Emitter {
debug(`got final outdial error: ${err}`);
if (!passFailure) this.res.send(status);
this.emit('failed');
this.rtpEngineResource.destroy();
this.rtpEngineResource.destroy()
.catch((err) => this.logger.info({err}, 'Error destroying rtpe after failure'));
const tags = ['accepted:no', `sipStatus:${status}`];
this.stats.increment('sbc.originations', tags);
@@ -375,8 +396,9 @@ class CallSession extends Emitter {
}
}
} catch (err) {
if ('abandonded' !== err.message) this.logger.error(err, `Error setting up outbonund call to: ${uris}`);
if ('abandonded' !== err.message) this.logger.error(err, `Error setting up outbound call to: ${uris}`);
this.emit('failed');
this.srf.endSession(this.req);
this.rtpEngineResource.destroy();
}
}
@@ -422,6 +444,7 @@ class CallSession extends Emitter {
duration: Math.floor((now - callStart) / 1000)
}).catch((err) => this.logger.error({err}, 'Error writing cdr for completed call'));
}
this.srf.endSession(this.req);
});
});
@@ -432,6 +455,7 @@ class CallSession extends Emitter {
uac.on('modify', this._onReinvite.bind(this, uac));
uas.on('refer', this._onFeatureServerTransfer.bind(this, uas));
uac.on('refer', this._onRefer.bind(this, uac));
uas.on('info', this._onInfo.bind(this, uas));
uac.on('info', this._onInfo.bind(this, uac));
@@ -440,6 +464,23 @@ class CallSession extends Emitter {
forwardInDialogRequests(uac, ['notify', 'options', 'message']);
}
async _onRefer(dlg, req, res) {
/* REFER coming in from a sip device, forward to feature server */
try {
const response = await dlg.other.request({
method: 'REFER',
headers: {
'Refer-To': req.get('Refer-To'),
'Referred-By': req.get('Referred-By'),
'User-Agent': req.get('User-Agent')
}
});
res.send(response.status, response.reason);
} catch (err) {
this.logger.error({err}, 'CallSession:_onRefer: error handling incoming REFER');
}
}
async _onDTMF(dlg, payload) {
this.logger.info({payload}, '_onDTMF');
try {
@@ -484,7 +525,8 @@ Duration=${payload.duration} `
direction,
sdp: req.body,
};
if (reason) opts.flags.push('reset');
if (reason && opts.flags && !opts.flags.includes('reset')) opts.flags.push('reset');
let response = await this.offer(opts);
if ('ok' !== response.result) {
@@ -500,6 +542,7 @@ Duration=${payload.duration} `
}
else {
sdp = await dlg.other.modify(response.sdp);
this.logger.info({sdp}, 'CallSession:_onReinvite: got sdp from 200 OK to invite we sent');
}
opts = {
...this.rtpEngineOpts.common,
@@ -513,6 +556,7 @@ Duration=${payload.duration} `
res.send(488);
throw new Error(`_onReinvite: rtpengine failed: ${JSON.stringify(response)}`);
}
this.logger.info({sdp: response.sdp}, 'CallSession:_onReinvite: sending back upstream');
res.send(200, {body: response.sdp});
} catch (err) {
this.logger.error(err, 'Error handling reinvite');
@@ -598,6 +642,7 @@ Duration=${payload.duration} `
this.rtpEngineResource.destroy();
this.activeCallIds.delete(this.req.get('Call-ID'));
this.uas.other.destroy();
this.srf.endSession(this.req);
});
// modify rtpengine to stream to new feature server
+52 -35
View File
@@ -2,15 +2,10 @@ const debug = require('debug')('jambonz:sbc-outbound');
const parseUri = require('drachtio-srf').parseUri;
const Registrar = require('@jambonz/mw-registrar');
const {selectHostPort, makeCallCountKey} = require('./utils');
const isLocalUri = (host, req) => {
debug({hostport: req.server.hostport}, `is ${host} local?`);
return req.server.hostport.includes(host);
};
const FS_UUID_SET_NAME = 'fsUUIDs';
module.exports = (srf, logger, opts) => {
const {incrKey, decrKey} = srf.locals.realtimeDbHelpers;
const {incrKey, decrKey, isMemberOfSet} = srf.locals.realtimeDbHelpers;
const {stats} = srf.locals;
const registrar = new Registrar(opts);
const {
@@ -26,13 +21,44 @@ module.exports = (srf, logger, opts) => {
if (!req.locals.account_sid) {
logger.info('missing X-Account-Sid on outbound call');
return res.send(403, {
res.send(403, {
headers: {
'X-Reason': 'missing X-Account-Sid'
}
});
return req.srf.endSession(req);
}
/* must come from a valid FS */
if (!req.has('X-Jambonz-Routing')) {
logger.info({msg: req.msg}, 'missing X-Jambonz-Routing header');
res.send(403, {
headers: {
'X-Reason': 'missing required jambonz headers'
}
});
return req.srf.endSession(req);
}
if (process.env.K8S) {
/* for K8S we do not use JAMBONES_CIDR so we must validate the sender by uuid FS creates */
const fsUUID = req.get('X-Jambonz-FS-UUID');
try {
const exists = await isMemberOfSet(FS_UUID_SET_NAME, fsUUID);
if (!exists || !fsUUID) {
res.send(403, {
headers: {
'X-Reason': `missing or invalid FS-UUID ${fsUUID}`
}
});
return req.srf.endSession(req);
}
} catch (err) {
res.send(500);
return req.srf.endSession(req);
}
}
stats.increment('sbc.invites', ['direction:outbound']);
req.on('cancel', () => {
@@ -47,7 +73,8 @@ module.exports = (srf, logger, opts) => {
req.locals.account = await lookupAccountBySid(req.locals.account_sid);
} catch (err) {
req.locals.logger.error({err}, `Error looking up account sid ${req.locals.account_sid}`);
return res.send(500);
res.send(500);
return req.srf.endSession(req);
}
next();
};
@@ -106,6 +133,7 @@ module.exports = (srf, logger, opts) => {
}).catch((err) => logger.info({err}, 'checkLimits: error writing alert'));
res.send(503, 'Maximum Calls In Progress');
return req.srf.endSession(req);
}
next();
} catch (err) {
@@ -119,6 +147,7 @@ module.exports = (srf, logger, opts) => {
const {lookupAccountBySipRealm} = req.srf.locals.dbHelpers;
logger.info(`received outbound INVITE to ${req.uri} from server at ${req.server.hostport}`);
const uri = parseUri(req.uri);
const desiredRouting = req.get('X-Jambonz-Routing');
if (!uri || !uri.user || !uri.host) {
logger.info({uri: req.uri}, 'invalid request-uri on outbound call, rejecting');
@@ -127,23 +156,17 @@ module.exports = (srf, logger, opts) => {
'X-Reason': 'invalid request-uri'
}
});
return;
return req.srf.endSession(req);
}
const aor = `${uri.user}@${uri.host}`;
let reg;
const dotDecimalHost = /^[0-9\.]+$/.test(uri.host);
debug(`received outbound INVITE to ${req.calledNumber} from server at ${req.server.hostport}`);
if (req.has('X-MS-Teams-FQDN') && req.has('X-MS-Teams-Tenant-FQDN')) {
if ('teams' === desiredRouting) {
logger.debug('This is a call to ms teams');
req.locals.target = 'teams';
return next();
}
else if (!dotDecimalHost) {
// uri host is not a dot-decimal address, so try to look up user
logger.debug(`searching for registered user ${aor}`);
reg = await registrar.query(aor);
else if ('user' === desiredRouting) {
const aor = `${uri.user}@${uri.host}`;
const reg = await registrar.query(aor);
if (reg) {
// user is registered..find out which sbc is handling it
// us => we can put the call through
@@ -158,34 +181,28 @@ module.exports = (srf, logger, opts) => {
}
req.locals.registration = reg;
req.locals.target = 'user';
return next();
}
else {
// if the sip domain is one of ours return 404
const account = await lookupAccountBySipRealm(uri.host);
if (account) {
logger.info({host: uri.host, account}, `returning 404 to unregistered user in valid domain: ${req.uri}`);
res.send(404);
return;
}
else {
logger.info({host: uri.host, account}, `returning 404 to user in invalid domain: ${req.uri}`);
}
res.send(404);
return req.srf.endSession(req);
}
}
if (!dotDecimalHost || !isLocalUri(uri.host, req)) {
else if ('sip' === desiredRouting) {
// call that needs to be forwarded to a sip endpoint
logger.info(`forwarding call to sip endpoint ${req.uri}`);
req.locals.target = 'forward';
return next();
}
// if the called number is digits only (after possible leading plus sign), do lcr
if (!/^\d+$/.test(req.calledNumber.slice(1))) {
debug(`unable to route call to ${aor}; no registered user found`);
logger.info(`unable to route call to ${aor}; no registered user found`);
return res.send(404);
else if ('phone' === desiredRouting) {
debug('sending call to LCR');
req.locals.target = 'lcr';
}
debug('sending call to LCR');
req.locals.target = 'lcr';
next();
};
+13 -1
View File
@@ -73,9 +73,21 @@ const pingMsTeamsGateways = (logger, srf) => {
const makeCallCountKey = (sid) => `${sid}:outcalls`;
const equalsIgnoreOrder = (a, b) => {
if (a.length !== b.length) return false;
const uniqueValues = new Set([...a, ...b]);
for (const v of uniqueValues) {
const aCount = a.filter((e) => e === v).length;
const bCount = b.filter((e) => e === v).length;
if (aCount !== bCount) return false;
}
return true;
};
module.exports = {
makeRtpEngineOpts,
selectHostPort,
pingMsTeamsGateways,
makeCallCountKey
makeCallCountKey,
equalsIgnoreOrder
};
+2891 -287
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -1,9 +1,9 @@
{
"name": "sbc-outbound",
"version": "v0.7.1",
"version": "v0.7.3",
"main": "app.js",
"engines": {
"node": ">= 8.10.0"
"node": ">= 12.0.0"
},
"keywords": [
"sip",
@@ -27,16 +27,18 @@
"jslint": "eslint app.js lib"
},
"dependencies": {
"@jambonz/db-helpers": "^0.6.14",
"@jambonz/mw-registrar": "0.2.1",
"@jambonz/realtimedb-helpers": "^0.4.9",
"@jambonz/rtpengine-utils": "^0.1.21",
"@jambonz/db-helpers": "^0.6.17",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/mw-registrar": "0.2.2",
"@jambonz/realtimedb-helpers": "^0.4.24",
"@jambonz/rtpengine-utils": "^0.3.1",
"@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.1.6",
"cidr-matcher": "^2.1.1",
"debug": "^4.3.3",
"drachtio-fn-b2b-sugar": "^0.0.12",
"drachtio-srf": "^4.4.59",
"husky": "^7.0.4",
"pino": "^7.4.1"
},
"devDependencies": {
+2 -1
View File
@@ -10,6 +10,7 @@ networks:
services:
mysql:
image: mysql:5.7
platform: linux/x86_64
ports:
- "3306:3306"
environment:
@@ -118,7 +119,7 @@ services:
ipv4_address: 172.39.0.24
influxdb:
image: influxdb:1.8-alpine
image: influxdb:1.8
ports:
- "8086:8086"
networks:
+1 -1
View File
@@ -36,6 +36,7 @@
Subject: uac-pcap-carrier-success
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: fff49e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: phone
Content-Type: application/sdp
Content-Length: [len]
@@ -103,4 +104,3 @@
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
</scenario>
@@ -34,6 +34,7 @@
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: uac-device-unknown-user
X-Jambonz-Routing: user
Content-Type: application/sdp
Content-Length: [len]
@@ -34,6 +34,7 @@
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: uac-device-unknown-user
X-Jambonz-Routing: user
Content-Type: application/sdp
Content-Length: [len]
@@ -34,6 +34,7 @@
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: uac-device-unknown-user
X-Jambonz-Routing: user
Content-Type: application/sdp
Content-Length: [len]
@@ -16,6 +16,7 @@
Max-Forwards: 70
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: ff49e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: phone
Subject: uac-pcap-carrier-fail-limits
Content-Type: application/sdp
Content-Length: [len]
@@ -17,6 +17,7 @@
Subject: uac-pcap-carrier-success
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: fff49e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: phone
Content-Type: application/sdp
Content-Length: [len]
@@ -16,6 +16,7 @@
Max-Forwards: 70
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: fff49e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: phone
Subject: uac-pcap-carrier-success
Content-Type: application/sdp
Content-Length: [len]
+1
View File
@@ -37,6 +37,7 @@
Subject: uac-pcap-device-success
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: ff649e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: user
Content-Type: application/sdp
Content-Length: [len]
@@ -34,6 +34,7 @@
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: uac-pcap-device-success
X-Jambonz-Routing: user
Content-Type: application/sdp
Content-Length: [len]
@@ -35,6 +35,7 @@
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: uac-pcap-device-success
X-Jambonz-Routing: user
Content-Type: application/sdp
Content-Length: [len]
+3 -1
View File
@@ -37,6 +37,7 @@
Subject: uac-sip-uri-auth-success
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: fff49e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: sip
Content-Type: application/sdp
Content-Length: [len]
@@ -90,6 +91,7 @@
Subject: uac-sip-uri-auth-success
X-Account-Sid: ed649e33-e771-403a-8c99-1780eabbc803
X-Call-Sid: fff49e33-e771-403a-8c99-1780eabbc803
X-Jambonz-Routing: sip
Content-Type: application/sdp
Content-Length: [len]
@@ -126,7 +128,7 @@
To: <sip:sip:john@jambonz.org>[peer_tag_param]
[last_Call-ID:]
CSeq: 2 ACK
Subject: uac-sip-uri-auth-success
Subject:
Content-Length: 0
]]>