From 9c952f2f8e10a152824fb81d9c6c44d1be7c4a0d Mon Sep 17 00:00:00 2001 From: Razvan Crainea Date: Tue, 26 Sep 2023 16:28:32 +0300 Subject: [PATCH] dialog: add 05.reinvite-auth test (cherry picked from commit 4c3bfdcefe78adfdbcbe1a9056ab1af451870487) --- README.md | 4 + dialog/05.reinvite-auth/defines.yml | 3 + dialog/05.reinvite-auth/opensips.cfg | 121 ++++++++ dialog/05.reinvite-auth/opensips.sql | 43 +++ dialog/05.reinvite-auth/scenario.yml | 50 ++++ .../05.reinvite-auth/scripts/check-dialog.py | 39 +++ .../05.reinvite-auth/scripts/mysql-dialog.sh | 10 + dialog/05.reinvite-auth/scripts/uac.xml | 172 +++++++++++ dialog/05.reinvite-auth/scripts/uas.xml | 277 ++++++++++++++++++ 9 files changed, 719 insertions(+) create mode 100644 dialog/05.reinvite-auth/defines.yml create mode 100644 dialog/05.reinvite-auth/opensips.cfg create mode 100644 dialog/05.reinvite-auth/opensips.sql create mode 100644 dialog/05.reinvite-auth/scenario.yml create mode 100644 dialog/05.reinvite-auth/scripts/check-dialog.py create mode 100644 dialog/05.reinvite-auth/scripts/mysql-dialog.sh create mode 100644 dialog/05.reinvite-auth/scripts/uac.xml create mode 100644 dialog/05.reinvite-auth/scripts/uas.xml diff --git a/README.md b/README.md index 5db55ee..fb94622 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,10 @@ Similar to [02.pinging](#02pinging), but checks that re-INVITE pinging is workin Similar to [01.dialog](#01simple), but expires the dialog before a BYE is received. +#### 05.reinvite-auth + +Runs a call through dialog where the re-INVITE is challenged by the UAC. + ### Topology Hiding Runs a set of calls using the topology hiding scenario, verifying that the UAS diff --git a/dialog/05.reinvite-auth/defines.yml b/dialog/05.reinvite-auth/defines.yml new file mode 100644 index 0000000..5c39719 --- /dev/null +++ b/dialog/05.reinvite-auth/defines.yml @@ -0,0 +1,3 @@ +--- +uac_ip: 192.168.52.2 + diff --git a/dialog/05.reinvite-auth/opensips.cfg b/dialog/05.reinvite-auth/opensips.cfg new file mode 100644 index 0000000..de30cec --- /dev/null +++ b/dialog/05.reinvite-auth/opensips.cfg @@ -0,0 +1,121 @@ +# +# OpenSIPS residential configuration script +# by OpenSIPS Solutions +# +# This script was generated via "make menuconfig", from +# the "Residential" scenario. +# You can enable / disable more features / functionalities by +# re-generating the scenario with different options.# +# +# Please refer to the Core CookBook at: +# https://opensips.org/Resources/DocsCookbooks +# for a explanation of possible statements, functions and parameters. +# + + +####### Global Parameters ######### +###################################################################### +/* uncomment the following lines to enable debugging */ +#debug_mode=yes + +log_level=4 +xlog_level=4 +log_stderror=yes + +udp_workers=4 + +####### Modules Section ######## + +#set module path +mpath="/usr/lib/x86_64-linux-gnu/opensips/modules/" + +#### SIGNALING module +loadmodule "signaling.so" + +#### StateLess module +loadmodule "sl.so" + +#### Transaction Module +loadmodule "tm.so" +modparam("tm", "fr_timeout", 5) +modparam("tm", "fr_inv_timeout", 30) +modparam("tm", "restart_fr_on_each_reply", 0) +modparam("tm", "onreply_avp_mode", 1) + +#### SIP MSG OPerationS module +loadmodule "sipmsgops.so" + +#### Dialog module +loadmodule "dialog.so" +modparam("dialog", "db_mode", 0) + +#### MAX ForWarD module +loadmodule "maxfwd.so" + +#### Record Route Module +loadmodule "rr.so" +/* do not append from tag to the RR (no need for this script) */ +modparam("rr", "append_fromtag", 0) + +loadmodule "proto_udp.so" + +loadmodule "httpd.so" +loadmodule "mi_http.so" + +####### Routing Logic ######## + +# main request routing logic + +route { + + if (!mf_process_maxfwd_header(10)) { + send_reply(483,"Too Many Hops"); + exit; + } + + if (has_totag()) { + + # handle hop-by-hop ACK (no routing required) + if (is_method("ACK") && t_check_trans()) { + t_relay(); + exit; + } + + # sequential request within a dialog should + # take the path determined by record-routing + if (!loose_route() && !match_dialog()) { + # we do record-routing for all our traffic, so we should not + # receive any sequential requests without Route hdr. + send_reply(404,"Not here"); + exit; + } + + # route it out to whatever destination was set by loose_route() + # in $du (destination URI). + t_relay(); + exit; + } + + # CANCEL processing + if (is_method("CANCEL")) { + if (t_check_trans()) + t_relay(); + exit; + } + + # accept just INVITE requests + if (!is_method("INVITE")) { + send_reply(503, "Service Unavailable"); + exit; + } + + if (!create_dialog()) { + send_reply(500, "Internal Server Error"); + exit; + } + record_route(); + + if (!t_relay()) + send_reply(500, "Internal Error"); + exit; +} diff --git a/dialog/05.reinvite-auth/opensips.sql b/dialog/05.reinvite-auth/opensips.sql new file mode 100644 index 0000000..37dee1d --- /dev/null +++ b/dialog/05.reinvite-auth/opensips.sql @@ -0,0 +1,43 @@ +GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'; +CREATE DATABASE opensips; + +USE opensips; + +CREATE TABLE version ( + table_name CHAR(32) NOT NULL, + table_version INT UNSIGNED DEFAULT 0 NOT NULL, + CONSTRAINT t_name_idx UNIQUE (table_name) +) ENGINE=InnoDB; + +INSERT INTO version (table_name, table_version) values ('dialog','12'); +CREATE TABLE dialog ( + dlg_id BIGINT(10) UNSIGNED PRIMARY KEY NOT NULL, + callid CHAR(255) NOT NULL, + from_uri CHAR(255) NOT NULL, + from_tag CHAR(64) NOT NULL, + to_uri CHAR(255) NOT NULL, + to_tag CHAR(64) NOT NULL, + mangled_from_uri CHAR(64) DEFAULT NULL, + mangled_to_uri CHAR(64) DEFAULT NULL, + caller_cseq CHAR(11) NOT NULL, + callee_cseq CHAR(11) NOT NULL, + caller_ping_cseq INT(11) UNSIGNED NOT NULL, + callee_ping_cseq INT(11) UNSIGNED NOT NULL, + caller_route_set TEXT(512), + callee_route_set TEXT(512), + caller_contact CHAR(255), + callee_contact CHAR(255), + caller_sock CHAR(64) NOT NULL, + callee_sock CHAR(64) NOT NULL, + state INT(10) UNSIGNED NOT NULL, + start_time INT(10) UNSIGNED NOT NULL, + timeout INT(10) UNSIGNED NOT NULL, + vars BLOB(4096) DEFAULT NULL, + profiles TEXT(512) DEFAULT NULL, + script_flags CHAR(255) DEFAULT NULL, + module_flags INT(10) UNSIGNED DEFAULT 0 NOT NULL, + flags INT(10) UNSIGNED DEFAULT 0 NOT NULL, + rt_on_answer CHAR(64) DEFAULT NULL, + rt_on_timeout CHAR(64) DEFAULT NULL, + rt_on_hangup CHAR(64) DEFAULT NULL +) ENGINE=InnoDB; diff --git a/dialog/05.reinvite-auth/scenario.yml b/dialog/05.reinvite-auth/scenario.yml new file mode 100644 index 0000000..f8b2df7 --- /dev/null +++ b/dialog/05.reinvite-auth/scenario.yml @@ -0,0 +1,50 @@ +--- +timeout: 10 + +tasks: + - name: OpenSIPS + type: opensips + + - name: SIPP UAS + type: uas-sipp + username: {{ username }} + password: {{ password }} + config_file: scripts/uas.xml + duration: 2000 # duration before re-INVITE and BYE + args: -auth_uri {{ uac_ip }}:{{ uac_port }} + require: OpenSIPS + + - name: SIPP UAC + type: uac-sipp + service: {{ username }} + config_file: scripts/uac.xml + remote: {{ uas_ip }}:{{ uas_port }} + ip: {{ uac_ip }} + caller: caller + keys: + username: {{ username }} + password: {{ password }} + nonce: {{ nonce }} + require: + - started: + task: SIPP UAS + wait: 0.5 + - after: + task: OpenSIPS + wait: 0.5 + + - name: MI check active + type: opensips-cli + script: scripts/check-dialog.py + args: active + require: + started: + task: SIPP UAC + wait: 2 + + # dialog should be deleted after SIPP finishes + - name: MI check deleted + type: opensips-cli + script: scripts/check-dialog.py + args: deleted + require: SIPP UAC diff --git a/dialog/05.reinvite-auth/scripts/check-dialog.py b/dialog/05.reinvite-auth/scripts/check-dialog.py new file mode 100644 index 0000000..d45b1fd --- /dev/null +++ b/dialog/05.reinvite-auth/scripts/check-dialog.py @@ -0,0 +1,39 @@ +from opensipscli import cli +import sys + +handler = cli.OpenSIPSCLI() + +if len(sys.argv) < 1: + sys.exit(-1) + +dialogs = handler.mi("dlg_list")['Dialogs'] +if sys.argv[1] == "active": + out = handler.mi("get_statistics", {"statistics" : ["active_dialogs"]}) + if out["dialog:active_dialogs"] != 1: + print("Active dialogs: {}".format(out["dialog:active_dialogs"])) + sys.exit(11) + if len(dialogs) != 1: + print("Number of dialogs: {}".format(len(dialogs))) + sys.exit(12) +elif sys.argv[1] == "deleted": + out = handler.mi("get_statistics", {"statistics" : ["dialog:"]}) + if out["dialog:active_dialogs"] != 0: + print("Active dialogs: {}".format(out["dialog:active_dialogs"])) + sys.exit(21) + if len(dialogs) != 0: + if len(dialogs) > 1: + print("Too many dialogs: {}".format(len(dialogs))) + sys.exit(22) + if dialogs[0]['state'] != 5: + print("Bad state {} for dialog".format(dialogs[0]['state'])) + sys.exit(23) + if out["dialog:failed_dialogs"] != 0: + print("Failed dialogs: {}".format(out["dialog:failed_dialogs"])) + sys.exit(24) + if out["dialog:expired_dialogs"] != 0: + print("Expired dialogs: {}".format(out["dialog:expired_dialogs"])) + sys.exit(25) + if out["dialog:processed_dialogs"] < 1: + print("Processed dialogs: {}".format(out["dialog:processed_dialogs"])) + sys.exit(26) +sys.exit(0) diff --git a/dialog/05.reinvite-auth/scripts/mysql-dialog.sh b/dialog/05.reinvite-auth/scripts/mysql-dialog.sh new file mode 100644 index 0000000..fd9357c --- /dev/null +++ b/dialog/05.reinvite-auth/scripts/mysql-dialog.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +l=$(mysql opensips -Nse 'select count(*) from dialog') +if [ "$1" = "active" ]; then + [ "$l" == "1" ] && exit 0 +else + [ "$l" == "0" ] && exit 0 +fi +echo "ERROR: number of dialogs is $l" +exit 1 diff --git a/dialog/05.reinvite-auth/scripts/uac.xml b/dialog/05.reinvite-auth/scripts/uac.xml new file mode 100644 index 0000000..767d25f --- /dev/null +++ b/dialog/05.reinvite-auth/scripts/uac.xml @@ -0,0 +1,172 @@ + + + + + + + + + + + ;tag=[call_number] + To: + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: + 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 + + ]]> + + + + + + + + + + + + + + + + + + ;tag=[call_number] + To: [peer_tag_param] + [routes] + CSeq: 1 ACK + Contact: + Call-ID: [call_id] + Max-Forwards: 70 + Subject: Performance Test + User-Agent: sipp + Content-Length: 0 + + ]]> + + + + + + + + + + + diff --git a/dialog/05.reinvite-auth/scripts/uas.xml b/dialog/05.reinvite-auth/scripts/uas.xml new file mode 100644 index 0000000..cc4600d --- /dev/null +++ b/dialog/05.reinvite-auth/scripts/uas.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Content-Length: 0 + + ]]> + + + + + + + Content-Length: 0 + + ]]> + + + + + + + + + + + + + + + + + + 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 + + ]]> + + + + + + + + + + + + + + + + + + + + Call-ID: [call_id] + Max-Forwards: 70 + 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 + a=sendonly + + ]]> + + + + + + + + + + + + + + + Call-ID: [call_id] + Max-Forwards: 70 + [authentication] + Content-Type: application/sdp + Content-Length: 0 + + ]]> + + + + + Call-ID: [call_id] + Max-Forwards: 70 + [authentication username=testing] + 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 + a=sendonly + + ]]> + + + + + + + + + + + + + + + Call-ID: [call_id] + Max-Forwards: 70 + [authentication] + Content-Type: application/sdp + Content-Length: 0 + + ]]> + + + + + + + Call-ID: [call_id] + Max-Forwards: 70 + [authentication username=testing] + Content-Length: 0 + + ]]> + + + + + + + + + + + + + + + + + + + + + + +