mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2025-12-19 04:37:43 +00:00
initial checkin
This commit is contained in:
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
test/*
|
||||||
126
.eslintrc.json
Normal file
126
.eslintrc.json
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"jsx": false,
|
||||||
|
"modules": false
|
||||||
|
},
|
||||||
|
"ecmaVersion": 2017
|
||||||
|
},
|
||||||
|
"plugins": ["promise"],
|
||||||
|
"rules": {
|
||||||
|
"promise/always-return": "error",
|
||||||
|
"promise/no-return-wrap": "error",
|
||||||
|
"promise/param-names": "error",
|
||||||
|
"promise/catch-or-return": "error",
|
||||||
|
"promise/no-native": "off",
|
||||||
|
"promise/no-nesting": "warn",
|
||||||
|
"promise/no-promise-in-callback": "warn",
|
||||||
|
"promise/no-callback-in-promise": "warn",
|
||||||
|
"promise/no-return-in-finally": "warn",
|
||||||
|
|
||||||
|
// Possible Errors
|
||||||
|
// http://eslint.org/docs/rules/#possible-errors
|
||||||
|
"comma-dangle": [2, "only-multiline"],
|
||||||
|
"no-control-regex": 2,
|
||||||
|
"no-debugger": 2,
|
||||||
|
"no-dupe-args": 2,
|
||||||
|
"no-dupe-keys": 2,
|
||||||
|
"no-duplicate-case": 2,
|
||||||
|
"no-empty-character-class": 2,
|
||||||
|
"no-ex-assign": 2,
|
||||||
|
"no-extra-boolean-cast" : 2,
|
||||||
|
"no-extra-parens": [2, "functions"],
|
||||||
|
"no-extra-semi": 2,
|
||||||
|
"no-func-assign": 2,
|
||||||
|
"no-invalid-regexp": 2,
|
||||||
|
"no-irregular-whitespace": 2,
|
||||||
|
"no-negated-in-lhs": 2,
|
||||||
|
"no-obj-calls": 2,
|
||||||
|
"no-proto": 2,
|
||||||
|
"no-unexpected-multiline": 2,
|
||||||
|
"no-unreachable": 2,
|
||||||
|
"use-isnan": 2,
|
||||||
|
"valid-typeof": 2,
|
||||||
|
|
||||||
|
// Best Practices
|
||||||
|
// http://eslint.org/docs/rules/#best-practices
|
||||||
|
"no-fallthrough": 2,
|
||||||
|
"no-octal": 2,
|
||||||
|
"no-redeclare": 2,
|
||||||
|
"no-self-assign": 2,
|
||||||
|
"no-unused-labels": 2,
|
||||||
|
|
||||||
|
// Strict Mode
|
||||||
|
// http://eslint.org/docs/rules/#strict-mode
|
||||||
|
"strict": [2, "never"],
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
// http://eslint.org/docs/rules/#variables
|
||||||
|
"no-delete-var": 2,
|
||||||
|
"no-undef": 2,
|
||||||
|
"no-unused-vars": [2, {"args": "none"}],
|
||||||
|
|
||||||
|
// Node.js and CommonJS
|
||||||
|
// http://eslint.org/docs/rules/#nodejs-and-commonjs
|
||||||
|
"no-mixed-requires": 2,
|
||||||
|
"no-new-require": 2,
|
||||||
|
"no-path-concat": 2,
|
||||||
|
"no-restricted-modules": [2, "sys", "_linklist"],
|
||||||
|
|
||||||
|
// Stylistic Issues
|
||||||
|
// http://eslint.org/docs/rules/#stylistic-issues
|
||||||
|
"comma-spacing": 2,
|
||||||
|
"eol-last": 2,
|
||||||
|
"indent": [2, 2, {"SwitchCase": 1}],
|
||||||
|
"keyword-spacing": 2,
|
||||||
|
"max-len": [2, 120, 2],
|
||||||
|
"new-parens": 2,
|
||||||
|
"no-mixed-spaces-and-tabs": 2,
|
||||||
|
"no-multiple-empty-lines": [2, {"max": 2}],
|
||||||
|
"no-trailing-spaces": [2, {"skipBlankLines": false }],
|
||||||
|
"quotes": [2, "single", "avoid-escape"],
|
||||||
|
"semi": 2,
|
||||||
|
"space-before-blocks": [2, "always"],
|
||||||
|
"space-before-function-paren": [2, "never"],
|
||||||
|
"space-in-parens": [2, "never"],
|
||||||
|
"space-infix-ops": 2,
|
||||||
|
"space-unary-ops": 2,
|
||||||
|
|
||||||
|
// ECMAScript 6
|
||||||
|
// http://eslint.org/docs/rules/#ecmascript-6
|
||||||
|
"arrow-parens": [2, "always"],
|
||||||
|
"arrow-spacing": [2, {"before": true, "after": true}],
|
||||||
|
"constructor-super": 2,
|
||||||
|
"no-class-assign": 2,
|
||||||
|
"no-confusing-arrow": 2,
|
||||||
|
"no-const-assign": 2,
|
||||||
|
"no-dupe-class-members": 2,
|
||||||
|
"no-new-symbol": 2,
|
||||||
|
"no-this-before-super": 2,
|
||||||
|
"prefer-const": 2
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"DTRACE_HTTP_CLIENT_REQUEST" : false,
|
||||||
|
"LTTNG_HTTP_CLIENT_REQUEST" : false,
|
||||||
|
"COUNTER_HTTP_CLIENT_REQUEST" : false,
|
||||||
|
"DTRACE_HTTP_CLIENT_RESPONSE" : false,
|
||||||
|
"LTTNG_HTTP_CLIENT_RESPONSE" : false,
|
||||||
|
"COUNTER_HTTP_CLIENT_RESPONSE" : false,
|
||||||
|
"DTRACE_HTTP_SERVER_REQUEST" : false,
|
||||||
|
"LTTNG_HTTP_SERVER_REQUEST" : false,
|
||||||
|
"COUNTER_HTTP_SERVER_REQUEST" : false,
|
||||||
|
"DTRACE_HTTP_SERVER_RESPONSE" : false,
|
||||||
|
"LTTNG_HTTP_SERVER_RESPONSE" : false,
|
||||||
|
"COUNTER_HTTP_SERVER_RESPONSE" : false,
|
||||||
|
"DTRACE_NET_STREAM_END" : false,
|
||||||
|
"LTTNG_NET_STREAM_END" : false,
|
||||||
|
"COUNTER_NET_SERVER_CONNECTION_CLOSE" : false,
|
||||||
|
"DTRACE_NET_SERVER_CONNECTION" : false,
|
||||||
|
"LTTNG_NET_SERVER_CONNECTION" : false,
|
||||||
|
"COUNTER_NET_SERVER_CONNECTION" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
|
||||||
|
# github pages site
|
||||||
|
_site
|
||||||
|
|
||||||
|
#transient test cases
|
||||||
|
examples/nosave.*.js
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
.nyc_output/
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directory
|
||||||
|
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
examples/*
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 jambonz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
19
app.js
Normal file
19
app.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
const Srf = require('drachtio-srf');
|
||||||
|
const srf = new Srf();
|
||||||
|
const config = require('config');
|
||||||
|
const logger = require('pino')(config.get('logging'));
|
||||||
|
const {auth} = require('./lib/middleware');
|
||||||
|
|
||||||
|
// disable logging in test mode
|
||||||
|
if (process.env.NODE_ENV === 'test') {
|
||||||
|
const noop = () => {};
|
||||||
|
logger.info = logger.debug = noop;
|
||||||
|
logger.child = () => {return {info: noop, error: noop, debug: noop};};
|
||||||
|
}
|
||||||
|
|
||||||
|
srf.listen(config.get('drachtio'));
|
||||||
|
|
||||||
|
srf.request('invite', auth);
|
||||||
|
srf.invite(require('./lib/invite')({logger}));
|
||||||
|
|
||||||
|
module.exports = {srf};
|
||||||
45
config/default.json
Normal file
45
config/default.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"drachtio": {
|
||||||
|
"port": 3002,
|
||||||
|
"secret": "cymru"
|
||||||
|
},
|
||||||
|
"rtpengine": {
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"port": 22222
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"level": "info"
|
||||||
|
},
|
||||||
|
"authCallback": {
|
||||||
|
"uri": "http://example.com/auth",
|
||||||
|
"auth": {
|
||||||
|
"username": "foo",
|
||||||
|
"password": "bar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"trunks": {
|
||||||
|
"inbound": [
|
||||||
|
{
|
||||||
|
"name": "carrier1",
|
||||||
|
"host": ["10.123.22.3"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"appserver": ["sip:10.10.120.1"]
|
||||||
|
},
|
||||||
|
"transcoding": {
|
||||||
|
"rtpCharacteristics" : {
|
||||||
|
"transport protocol": "RTP/AVP",
|
||||||
|
"DTLS": "off",
|
||||||
|
"SDES": "off",
|
||||||
|
"ICE": "remove",
|
||||||
|
"rtcp-mux": ["demux"]
|
||||||
|
},
|
||||||
|
"srtpCharacteristics": {
|
||||||
|
"transport-protocol": "UDP/TLS/RTP/SAVPF",
|
||||||
|
"ICE": "force",
|
||||||
|
"SDES": "off",
|
||||||
|
"flags": ["generate mid", "SDES-no"],
|
||||||
|
"rtcp-mux": ["require"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
config/local-test.json
Normal file
10
config/local-test.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"drachtio": {
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"port": 9060,
|
||||||
|
"secret": "cymru"
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"level": "info"
|
||||||
|
}
|
||||||
|
}
|
||||||
63
lib/invite.js
Normal file
63
lib/invite.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
const config = require('config');
|
||||||
|
const Client = require('rtpengine-client').Client ;
|
||||||
|
const rtpengine = new Client();
|
||||||
|
const offer = rtpengine.offer.bind(rtpengine, config.get('rtpengine'));
|
||||||
|
const answer = rtpengine.answer.bind(rtpengine, config.get('rtpengine'));
|
||||||
|
const del = rtpengine.delete.bind(rtpengine, config.get('rtpengine'));
|
||||||
|
const {getAppserver, isWSS} = require('./utils');
|
||||||
|
|
||||||
|
module.exports = handler;
|
||||||
|
|
||||||
|
function handler({logger}) {
|
||||||
|
return async(req, res) => {
|
||||||
|
const srf = req.srf;
|
||||||
|
const rtpEngineOpts = makeRtpEngineOpts(req, isWSS(req), false);
|
||||||
|
const rtpEngineResource = {destroy: del.bind(rtpengine, rtpEngineOpts.common)};
|
||||||
|
const uri = getAppserver();
|
||||||
|
logger.info(`received inbound INVITE from ${req.protocol}/${req.source_address}:${req.source_port}`);
|
||||||
|
try {
|
||||||
|
const response = await offer(rtpEngineOpts.offer);
|
||||||
|
if ('ok' !== response.result) {
|
||||||
|
res.send(480);
|
||||||
|
throw new Error(`failed allocating rtpengine endpoint: ${JSON.stringify(response)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const {uas, uac} = await srf.createB2BUA(req, res, {
|
||||||
|
proxy: uri,
|
||||||
|
localSdpB: response.sdp,
|
||||||
|
localSdpA: (sdp, res) => {
|
||||||
|
const opts = Object.assign({sdp, 'to-tag': res.getParsedHeader('To').params.tag},
|
||||||
|
rtpEngineOpts.answer);
|
||||||
|
return answer(opts)
|
||||||
|
.then((response) => {
|
||||||
|
if ('ok' !== response.result) throw new Error('error allocating rtpengine');
|
||||||
|
return response.sdp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
logger.info('call connected');
|
||||||
|
|
||||||
|
[uas, uac].forEach((dlg) => dlg.on('destroy', () => {
|
||||||
|
logger.info('call ended');
|
||||||
|
dlg.other.destroy();
|
||||||
|
rtpEngineResource.destroy();
|
||||||
|
}));
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err, 'Error connecting call');
|
||||||
|
rtpEngineResource.destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeRtpEngineOpts(req, srcIsUsingSrtp, dstIsUsingSrtp) {
|
||||||
|
const from = req.getParsedHeader('from');
|
||||||
|
const common = {'call-id': req.get('Call-ID'), 'from-tag': from.params.tag};
|
||||||
|
const rtpCharacteristics = config.get('transcoding.rtpCharacteristics');
|
||||||
|
const srtpCharacteristics = config.get('transcoding.srtpCharacteristics');
|
||||||
|
return {
|
||||||
|
common,
|
||||||
|
offer: Object.assign({'sdp': req.body, 'replace': ['origin', 'session-connection']}, common,
|
||||||
|
dstIsUsingSrtp ? srtpCharacteristics : rtpCharacteristics),
|
||||||
|
answer: Object.assign({}, common, srcIsUsingSrtp ? srtpCharacteristics : rtpCharacteristics)
|
||||||
|
};
|
||||||
|
}
|
||||||
12
lib/middleware.js
Normal file
12
lib/middleware.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const {fromInboundTrunk} = require('./utils');
|
||||||
|
const config = require('config');
|
||||||
|
const authenticator = require('drachtio-http-authenticator')(config.get('authCallback'));
|
||||||
|
|
||||||
|
function auth(req, res, next) {
|
||||||
|
if (fromInboundTrunk) return next();
|
||||||
|
authenticator(req, res, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
auth
|
||||||
|
};
|
||||||
24
lib/utils.js
Normal file
24
lib/utils.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const config = require('config');
|
||||||
|
let idx = 0;
|
||||||
|
|
||||||
|
function fromInboundTrunk(req) {
|
||||||
|
const trunks = config.has('trunks.inbound') ?
|
||||||
|
config.get('trunks.inbound') : [];
|
||||||
|
if (isWSS(req)) return false;
|
||||||
|
return trunks.find((trunk) => trunk.host.includes(req.source_address));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWSS(req) {
|
||||||
|
return req.getParsedHeader('Via')[0].protocol.toLowerCase().startsWith('ws');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAppserver() {
|
||||||
|
const len = config.get('trunks.appserver').length;
|
||||||
|
return config.get('trunks.appserver')[ idx++ % len];
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
fromInboundTrunk,
|
||||||
|
isWSS,
|
||||||
|
getAppserver
|
||||||
|
};
|
||||||
37
package.json
Normal file
37
package.json
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "sbc-inbound",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"main": "app.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.10.0"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"sip",
|
||||||
|
"drachtio"
|
||||||
|
],
|
||||||
|
"author": "",
|
||||||
|
"license": "",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node app",
|
||||||
|
"test": "NODE_ENV=test node test/ | ./node_modules/.bin/tap-spec",
|
||||||
|
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
|
||||||
|
"jslint": "eslint app.js lib"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"config": "^3.2.2",
|
||||||
|
"drachtio-http-authenticator": "0.0.2",
|
||||||
|
"drachtio-srf": "^4.4.14",
|
||||||
|
"pino": "^5.13.2",
|
||||||
|
"rtpengine-client": "0.0.8"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"blue-tape": "^1.0.0",
|
||||||
|
"clear-module": "^4.0.0",
|
||||||
|
"eslint": "^6.1.0",
|
||||||
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
|
"nyc": "^14.1.1",
|
||||||
|
"tap": "^14.6.1",
|
||||||
|
"tap-dot": "^2.0.0",
|
||||||
|
"tap-spec": "^5.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
32
test/docker-compose-testbed.yaml
Normal file
32
test/docker-compose-testbed.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
sbc-inbound:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.38.0.0/16
|
||||||
|
|
||||||
|
services:
|
||||||
|
drachtio:
|
||||||
|
image: drachtio/drachtio-server:latest
|
||||||
|
command: drachtio --contact "sip:*;transport=udp" --loglevel debug --sofia-loglevel 9
|
||||||
|
container_name: drachtio
|
||||||
|
ports:
|
||||||
|
- "9060:9022/tcp"
|
||||||
|
networks:
|
||||||
|
sbc-inbound:
|
||||||
|
ipv4_address: 172.38.0.10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sipp-uas:
|
||||||
|
image: drachtio/sipp:latest
|
||||||
|
command: sipp -sf /tmp/uas.xml
|
||||||
|
container_name: sipp-uas.local
|
||||||
|
volumes:
|
||||||
|
- ./scenarios:/tmp
|
||||||
|
tty: true
|
||||||
|
networks:
|
||||||
|
sbc-inbound:
|
||||||
|
ipv4_address: 172.38.0.12
|
||||||
12
test/docker_start.js
Normal file
12
test/docker_start.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const test = require('tape').test ;
|
||||||
|
const exec = require('child_process').exec ;
|
||||||
|
const async = require('async');
|
||||||
|
|
||||||
|
test('starting docker network..', (t) => {
|
||||||
|
exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => {
|
||||||
|
t.end(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
12
test/docker_stop.js
Normal file
12
test/docker_stop.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const test = require('tape').test ;
|
||||||
|
const exec = require('child_process').exec ;
|
||||||
|
|
||||||
|
test('stopping docker network..', (t) => {
|
||||||
|
t.timeoutAfter(10000);
|
||||||
|
exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => {
|
||||||
|
//console.log(`stderr: ${stderr}`);
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
t.end() ;
|
||||||
|
});
|
||||||
|
|
||||||
3
test/index.js
Normal file
3
test/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
require('./docker_start');
|
||||||
|
require('./sip-tests');
|
||||||
|
require('./docker_stop');
|
||||||
BIN
test/scenarios/pcap/g711a.pcap
Normal file
BIN
test/scenarios/pcap/g711a.pcap
Normal file
Binary file not shown.
44
test/scenarios/uac-info-expect-480.xml
Normal file
44
test/scenarios/uac-info-expect-480.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
INFO sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 INFO
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="480" rtd="true"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
44
test/scenarios/uac-message-expect-480.xml
Normal file
44
test/scenarios/uac-message-expect-480.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
MESSAGE sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 MESSAGE
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="480" rtd="true"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
44
test/scenarios/uac-options-expect-480.xml
Normal file
44
test/scenarios/uac-options-expect-480.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
OPTIONS sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 OPTIONS
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="480" rtd="true"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
123
test/scenarios/uac-pcap.xml
Normal file
123
test/scenarios/uac-pcap.xml
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp 'uac' scenario with pcap (rtp) play -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="UAC with media">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
INVITE sip:[service]@[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=[pid]SIPpTag09[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 INVITE
|
||||||
|
Contact: sip:sipp@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Type: application/sdp
|
||||||
|
Content-Length: [len]
|
||||||
|
|
||||||
|
v=0
|
||||||
|
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||||
|
s=-
|
||||||
|
c=IN IP[local_ip_type] [local_ip]
|
||||||
|
t=0 0
|
||||||
|
m=audio [auto_media_port] RTP/AVP 8 101
|
||||||
|
a=rtpmap:8 PCMA/8000
|
||||||
|
a=rtpmap:101 telephone-event/8000
|
||||||
|
a=fmtp:101 0-11,16
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="100" optional="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<recv response="180" optional="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||||
|
<!-- are saved and used for following messages sent. Useful to test -->
|
||||||
|
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||||
|
<recv response="200" rtd="true" crlf="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- Packet lost can be simulated in any send/recv message by -->
|
||||||
|
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
ACK sip:[service]@[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=[pid]SIPpTag09[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 ACK
|
||||||
|
Contact: sip:sipp@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<!-- Play a pre-recorded PCAP file (RTP stream) -->
|
||||||
|
<nop>
|
||||||
|
<action>
|
||||||
|
<exec play_pcap_audio="pcap/g711a.pcap"/>
|
||||||
|
</action>
|
||||||
|
</nop>
|
||||||
|
|
||||||
|
<!-- Pause 8 seconds, which is approximately the duration of the -->
|
||||||
|
<!-- PCAP file -->
|
||||||
|
<pause milliseconds="4000"/>
|
||||||
|
|
||||||
|
<!-- The 'crlf' option inserts a blank line in the statistics report. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
BYE sip:[service]@[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=[pid]SIPpTag09[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 2 BYE
|
||||||
|
Contact: sip:sipp@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="200" crlf="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- definition of the response time repartition table (unit is ms) -->
|
||||||
|
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||||
|
|
||||||
|
<!-- definition of the call length repartition table (unit is ms) -->
|
||||||
|
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
45
test/scenarios/uac-publish-expect-480.xml
Normal file
45
test/scenarios/uac-publish-expect-480.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
PUBLISH sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 PUBLISH
|
||||||
|
Contact: <sip:sipp@[local_ip]:[local_port]>;expires=3600
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="480" rtd="true"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
45
test/scenarios/uac-register-expect-480.xml
Normal file
45
test/scenarios/uac-register-expect-480.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
REGISTER sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 REGISTER
|
||||||
|
Contact: <sip:sipp@[local_ip]:[local_port]>;expires=3600
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="480" rtd="true"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
45
test/scenarios/uac-subscribe-expect-480.xml
Normal file
45
test/scenarios/uac-subscribe-expect-480.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SUBSCRIBE sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 SUBSCRIBE
|
||||||
|
Contact: <sip:sipp@[local_ip]:[local_port]>;expires=3600
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="480" rtd="true"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
118
test/scenarios/uac.xml
Normal file
118
test/scenarios/uac.xml
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uac' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic Sipstone UAC">
|
||||||
|
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||||
|
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
INVITE sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 INVITE
|
||||||
|
Contact: sip:sipp@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Type: application/sdp
|
||||||
|
Content-Length: [len]
|
||||||
|
|
||||||
|
v=0
|
||||||
|
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||||
|
s=-
|
||||||
|
c=IN IP[media_ip_type] [media_ip]
|
||||||
|
t=0 0
|
||||||
|
m=audio [media_port] RTP/AVP 0
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="100"
|
||||||
|
optional="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<recv response="180" optional="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<recv response="183" optional="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||||
|
<!-- are saved and used for following messages sent. Useful to test -->
|
||||||
|
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||||
|
<recv response="200" rtd="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- Packet lost can be simulated in any send/recv message by -->
|
||||||
|
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
ACK sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 1 ACK
|
||||||
|
Contact: sip:sipp@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<!-- This delay can be customized by the -d command-line option -->
|
||||||
|
<!-- or by adding a 'milliseconds = "value"' option here. -->
|
||||||
|
<pause/>
|
||||||
|
|
||||||
|
<!-- The 'crlf' option inserts a blank line in the statistics report. -->
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
BYE sip:[service]@[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=[pid]SIPpTag00[call_number]
|
||||||
|
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: 2 BYE
|
||||||
|
Contact: sip:sipp@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 70
|
||||||
|
Subject: Performance Test
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv response="200" crlf="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- definition of the response time repartition table (unit is ms) -->
|
||||||
|
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||||
|
|
||||||
|
<!-- definition of the call length repartition table (unit is ms) -->
|
||||||
|
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
120
test/scenarios/uas.xml
Normal file
120
test/scenarios/uas.xml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||||
|
|
||||||
|
<!-- This program is free software; you can redistribute it and/or -->
|
||||||
|
<!-- modify it under the terms of the GNU General Public License as -->
|
||||||
|
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||||
|
<!-- License, or (at your option) any later version. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- This program is distributed in the hope that it will be useful, -->
|
||||||
|
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||||
|
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||||
|
<!-- GNU General Public License for more details. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- You should have received a copy of the GNU General Public License -->
|
||||||
|
<!-- along with this program; if not, write to the -->
|
||||||
|
<!-- Free Software Foundation, Inc., -->
|
||||||
|
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Sipp default 'uas' scenario. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<scenario name="Basic UAS responder">
|
||||||
|
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||||
|
<!-- are saved and used for following messages sent. Useful to test -->
|
||||||
|
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||||
|
<recv request="INVITE" crlf="true">
|
||||||
|
<action>
|
||||||
|
<ereg regexp=".*" search_in="hdr" header="Subject:" assign_to="1" />
|
||||||
|
</action>
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!-- The '[last_*]' keyword is replaced automatically by the -->
|
||||||
|
<!-- specified header if it was present in the last message received -->
|
||||||
|
<!-- (except if it was a retransmission). If the header was not -->
|
||||||
|
<!-- present or if no message has been received, the '[last_*]' -->
|
||||||
|
<!-- keyword is discarded, and all bytes until the end of the line -->
|
||||||
|
<!-- are also discarded. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- If the specified header was present several times in the -->
|
||||||
|
<!-- message, all occurrences are concatenated (CRLF separated) -->
|
||||||
|
<!-- to be used in place of the '[last_*]' keyword. -->
|
||||||
|
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SIP/2.0 180 Ringing
|
||||||
|
[last_Via:]
|
||||||
|
[last_From:]
|
||||||
|
[last_To:];tag=[pid]SIPpTag01[call_number]
|
||||||
|
[last_Call-ID:]
|
||||||
|
[last_CSeq:]
|
||||||
|
[last_Record-Route:]
|
||||||
|
Subject:[$1]
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SIP/2.0 200 OK
|
||||||
|
[last_Via:]
|
||||||
|
[last_From:]
|
||||||
|
[last_To:];tag=[pid]SIPpTag01[call_number]
|
||||||
|
[last_Call-ID:]
|
||||||
|
[last_CSeq:]
|
||||||
|
[last_Record-Route:]
|
||||||
|
Subject:[$1]
|
||||||
|
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
|
||||||
|
Content-Type: application/sdp
|
||||||
|
Content-Length: [len]
|
||||||
|
|
||||||
|
v=0
|
||||||
|
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||||
|
s=-
|
||||||
|
c=IN IP[media_ip_type] [media_ip]
|
||||||
|
t=0 0
|
||||||
|
m=audio [media_port] RTP/AVP 0
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv request="ACK"
|
||||||
|
rtd="true"
|
||||||
|
crlf="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<recv request="BYE">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SIP/2.0 200 OK
|
||||||
|
[last_Via:]
|
||||||
|
[last_From:]
|
||||||
|
[last_To:]
|
||||||
|
[last_Call-ID:]
|
||||||
|
[last_CSeq:]
|
||||||
|
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<!-- Keep the call open for a while in case the 200 is lost to be -->
|
||||||
|
<!-- able to retransmit it if we receive the BYE again. -->
|
||||||
|
<timewait milliseconds="4000"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- definition of the response time repartition table (unit is ms) -->
|
||||||
|
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||||
|
|
||||||
|
<!-- definition of the call length repartition table (unit is ms) -->
|
||||||
|
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||||
|
|
||||||
|
</scenario>
|
||||||
|
|
||||||
40
test/sip-tests.js
Normal file
40
test/sip-tests.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
const test = require('blue-tape');
|
||||||
|
const { output, sippUac } = require('./sipp')('test_sbc-inbound');
|
||||||
|
const debug = require('debug')('drachtio:sbc-inbound');
|
||||||
|
const clearModule = require('clear-module');
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
function connect(connectable) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
connectable.on('connect', () => {
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
test('invite handler', (t) => {
|
||||||
|
clearModule('../app');
|
||||||
|
const {srf, disconnectMs} = require('../app');
|
||||||
|
|
||||||
|
connect(srf)
|
||||||
|
.then(() => {
|
||||||
|
return sippUac('uac-pcap.xml');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
t.pass('successfully connected call');
|
||||||
|
if (srf.locals.lb) srf.locals.lb.disconnect();
|
||||||
|
srf.disconnect();
|
||||||
|
t.end();
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (srf.locals.lb) srf.locals.lb.disconnect();
|
||||||
|
if (srf) srf.disconnect();
|
||||||
|
console.log(`error received: ${err}`);
|
||||||
|
t.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
65
test/sipp.js
Normal file
65
test/sipp.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
const { spawn } = require('child_process');
|
||||||
|
//const debug = require('debug')('test:sipp');
|
||||||
|
let network;
|
||||||
|
const obj = {};
|
||||||
|
let output = '';
|
||||||
|
let idx = 1;
|
||||||
|
|
||||||
|
function clearOutput() {
|
||||||
|
output = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOutput(str) {
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
if (str.charCodeAt(i) < 128) output += str.charAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (networkName) => {
|
||||||
|
network = networkName ;
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.output = () => {
|
||||||
|
return output;
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.sippUac = (file) => {
|
||||||
|
const cmd = 'docker';
|
||||||
|
const args = [
|
||||||
|
'run', '-ti', '--rm', '--net', `${network}`,
|
||||||
|
'-v', `${__dirname}/scenarios:/tmp/scenarios`,
|
||||||
|
'drachtio/sipp', 'sipp', '-sf', `/tmp/scenarios/${file}`,
|
||||||
|
'-m', '1',
|
||||||
|
'-sleep', '250ms',
|
||||||
|
'-nostdin',
|
||||||
|
'-cid_str', `%u-%p@%s-${idx++}`,
|
||||||
|
'drachtio'
|
||||||
|
];
|
||||||
|
|
||||||
|
clearOutput();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const child_process = spawn(cmd, args, {stdio: ['inherit', 'pipe', 'pipe']});
|
||||||
|
|
||||||
|
child_process.on('exit', (code, signal) => {
|
||||||
|
if (code === 0) {
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
console.log(`sipp exited with non-zero code ${code} signal ${signal}`);
|
||||||
|
reject(code);
|
||||||
|
});
|
||||||
|
child_process.on('error', (error) => {
|
||||||
|
console.log(`error spawing child process for docker: ${args}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
child_process.stdout.on('data', (data) => {
|
||||||
|
//debug(`stdout: ${data}`);
|
||||||
|
addOutput(data.toString());
|
||||||
|
});
|
||||||
|
child_process.stdout.on('data', (data) => {
|
||||||
|
//debug(`stdout: ${data}`);
|
||||||
|
addOutput(data.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user