2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* Author : Richard GAYRAUD - 04 Nov 2003
18
* From Hewlett Packard Company.
23
* Guillaume TEISSIER from FTR&D
25
* Marc Van Diest from Belgacom
26
* Charles P. Wright from IBM Research
32
#include <gsl/gsl_rng.h>
33
#include <gsl/gsl_randist.h>
34
#include <gsl/gsl_cdf.h>
36
/************************ Class Constructor *************************/
38
message::message(int index, const char *desc)
42
pause_distribution = NULL;
46
bShouldRecordRoutes = 0;
48
bShouldAuthenticate = 0;
60
regexp_compile = NULL;
72
condexec_inverse = false;
73
chance = 0;/* meaning always */
77
onTimeoutLabel = NULL;
80
/* 3pcc extended mode */
102
content_length_flag = ContentLengthNoPresent;
104
/* How to match responses to this message. */
108
recv_response_for_cseq_method_list = NULL;
113
if(M_actions != NULL)
116
if(send_scheme != NULL)
119
if(recv_request != NULL)
122
if(regexp_compile != NULL)
123
regfree(regexp_compile);
124
free(regexp_compile);
127
if (pause_distribution) {
128
delete pause_distribution;
131
if(M_sendCmdData != NULL)
132
delete M_sendCmdData;
138
free(recv_response_for_cseq_method_list);
141
/******** Global variables which compose the scenario file **********/
143
scenario *main_scenario;
144
scenario *ooc_scenario;
145
scenario *display_scenario;
147
/* This mode setting refers to whether we open calls autonomously (MODE_CLIENT)
148
* or in response to requests (MODE_SERVER). */
149
int creationMode = MODE_CLIENT;
150
/* Send mode. Do we send to a fixed address or to the last one we got. */
151
int sendMode = MODE_CLIENT;
152
/* This describes what our 3PCC behavior is. */
153
int thirdPartyMode = MODE_3PCC_NONE;
155
/*************** Helper functions for various types *****************/
156
long get_long(const char *ptr, const char *what) {
160
ret = strtol(ptr, &endptr, 0);
162
ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
167
unsigned long long get_long_long(const char *ptr, const char *what) {
169
unsigned long long ret;
171
ret = strtoull(ptr, &endptr, 0);
173
ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
178
/* This function returns a time in milliseconds from a string.
179
* The multiplier is used to convert from the default input type into
180
* milliseconds. For example, for seconds you should use 1000 and for
181
* milliseconds use 1. */
182
long get_time(const char *ptr, const char *what, int multiplier) {
189
if (!isdigit(*ptr)) {
190
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
193
for (i = 0, p = ptr; *p; p++) {
199
if (i == 1) { /* mm:ss */
200
ERROR("%s, \"%s\" mm:ss not implemented yet!\n", what, ptr);
202
else if (i == 2) { /* hh:mm:ss */
203
ERROR("%s, \"%s\" hh:mm:ss not implemented yet!\n", what, ptr);
205
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
208
dret = strtod(ptr, &endptr);
210
if (!strcmp(endptr, "s")) { /* Seconds */
211
ret = (long)(dret * 1000);
212
} else if (!strcmp(endptr, "ms")) { /* Milliseconds. */
214
} else if (!strcmp(endptr, "m")) { /* Minutes. */
215
ret = (long)(dret * 60000);
216
} else if (!strcmp(endptr, "h")) { /* Hours. */
217
ret = (long)(dret * 60 * 60 * 1000);
219
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
222
ret = (long)(dret * multiplier);
227
double get_double(const char *ptr, const char *what) {
231
ret = strtod(ptr, &endptr);
233
ERROR("%s, \"%s\" is not a floating point number!\n", what, ptr);
238
char * xp_get_string(const char *name, const char *what) {
241
if (!(ptr = xp_get_value(name))) {
242
ERROR("%s is missing the required '%s' parameter.", what, name);
248
double xp_get_double(const char *name, const char *what) {
253
if (!(ptr = xp_get_value(name))) {
254
ERROR("%s is missing the required '%s' parameter.", what, name);
256
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
257
sprintf(helptext, "%s '%s' parameter", what, name);
258
val = get_double(ptr, helptext);
264
double xp_get_double(const char *name, const char *what, double defval) {
265
if (!(xp_get_value(name))) {
268
return xp_get_double(name, what);
271
long xp_get_long(const char *name, const char *what) {
276
if (!(ptr = xp_get_value(name))) {
277
ERROR("%s is missing the required '%s' parameter.", what, name);
279
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
280
sprintf(helptext, "%s '%s' parameter", what, name);
281
val = get_long(ptr, helptext);
287
long xp_get_long(const char *name, const char *what, long defval) {
288
if (!(xp_get_value(name))) {
291
return xp_get_long(name, what);
295
double xp_get_bool(const char *name, const char *what) {
300
if (!(ptr = xp_get_value(name))) {
301
ERROR("%s is missing the required '%s' parameter.", what, name);
303
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
304
sprintf(helptext, "%s '%s' parameter", what, name);
305
val = get_bool(ptr, helptext);
311
double xp_get_bool(const char *name, const char *what, bool defval) {
312
if (!(xp_get_value(name))) {
315
return xp_get_bool(name, what);
318
int scenario::get_txn(const char *txnName, const char *what, bool start, bool isInvite, bool isAck) {
319
/* Check the name's validity. */
320
if (txnName[0] == '\0') {
321
ERROR("Variable names may not be empty for %s\n", what);
323
if (strcspn(txnName, "$,") != strlen(txnName)) {
324
ERROR("Variable names may not contain $ or , for %s\n", what);
327
/* If this transaction has already been used, then we have nothing to do. */
328
str_int_map::iterator txn_it = txnMap.find(txnName);
329
if (txn_it != txnMap.end()) {
331
/* We need to fill in the invite field. */
332
transactions[txn_it->second - 1].started++;
334
transactions[txn_it->second - 1].acks++;
336
transactions[txn_it->second - 1].responses++;
338
return txn_it->second;
341
/* Assign this variable the next slot. */
342
struct txnControlInfo transaction;
344
transaction.name = strdup(txnName);
346
transaction.started = 1;
347
transaction.responses = 0;
348
transaction.acks = 0;
349
transaction.isInvite = isInvite;
351
/* Does not start or respond to this txn. */
352
transaction.started = 0;
353
transaction.responses = 0;
354
transaction.acks = 1;
355
transaction.isInvite = false;
357
transaction.started = 0;
358
transaction.responses = 1;
359
transaction.acks = 0;
360
transaction.isInvite = false;
363
transactions.push_back(transaction);
364
int txnNum = transactions.size();
365
txnMap[txnName] = txnNum;
370
int scenario::find_var(const char *varName, const char *what) {
371
return allocVars->find(varName, false);
374
int scenario::get_var(const char *varName, const char *what) {
375
/* Check the name's validity. */
376
if (varName[0] == '\0') {
377
ERROR("Transaction names may not be empty for %s\n", what);
379
if (strcspn(varName, "$,") != strlen(varName)) {
380
ERROR("Transaction names may not contain $ or , for %s\n", what);
383
return allocVars->find(varName, true);
386
int scenario::xp_get_var(const char *name, const char *what) {
389
if (!(ptr = xp_get_value(name))) {
390
ERROR("%s is missing the required '%s' variable parameter.", what, name);
393
return get_var(ptr, what);
396
int xp_get_optional(const char *name, const char *what) {
397
char *ptr = xp_get_value(name);
399
if (!(ptr = xp_get_value(name))) {
400
return OPTIONAL_FALSE;
403
if(!strcmp(ptr, "true")) {
404
return OPTIONAL_TRUE;
405
} else if(!strcmp(ptr, "global")) {
406
return OPTIONAL_GLOBAL;
407
} else if(!strcmp(ptr, "false")) {
408
return OPTIONAL_FALSE;
410
ERROR("Could not understand optional value for %s: %s", what, ptr);
413
return OPTIONAL_FALSE;
417
int scenario::xp_get_var(const char *name, const char *what, int defval) {
420
if (!(ptr = xp_get_value(name))) {
424
return xp_get_var(name, what);
427
bool get_bool(const char *ptr, const char *what) {
431
if (!strcmp(ptr, "true")) {
434
if (!strcmp(ptr, "false")) {
438
ret = strtol(ptr, &endptr, 0);
440
ERROR("%s, \"%s\" is not a valid boolean!\n", what, ptr);
442
return ret ? true : false;
445
/* Pretty print a time. */
446
char *time_string(int ms) {
450
snprintf(tmp, sizeof(tmp), "%dms", ms);
451
} else if (ms < 100000) {
452
snprintf(tmp, sizeof(tmp), "%.1fs", ((float)ms)/1000);
454
snprintf(tmp, sizeof(tmp), "%ds", ms/1000);
460
int time_string(double ms, char *res, int reslen) {
462
/* Less then 10 seconds we represent accurately. */
463
if ((int)(ms + 0.9999) == (int)(ms)) {
464
/* We have an integer, or close enough to it. */
465
return snprintf(res, reslen, "%dms", (int)ms);
468
return snprintf(res, reslen, "%.2lfms", ms);
470
return snprintf(res, reslen, "%.1lfms", ms);
473
} else if (ms < 60000) {
474
/* We round to 100ms for times less than a minute. */
475
return snprintf(res, reslen, "%.1fs", ms/1000);
476
} else if (ms < 60 * 60000) {
477
/* We round to 1s for times more than a minute. */
478
int s = (unsigned int)(ms / 1000);
481
return snprintf(res, reslen, "%d:%02d", m, s);
483
int s = (unsigned int)(ms / 1000);
488
return snprintf(res, reslen, "%d:%02d:%02d", h, m, s);
492
char *double_time_string(double ms) {
496
snprintf(tmp, sizeof(tmp), "%.2lfms", ms);
497
} else if (ms < 10000) {
498
snprintf(tmp, sizeof(tmp), "%.1lfms", ms);
499
} else if (ms < 100000) {
500
snprintf(tmp, sizeof(tmp), "%.1lfs", ms / 1000);
502
snprintf(tmp, sizeof(tmp), "%ds", (int)(ms/1000));
508
/* For backwards compatibility, we assign "true" to slot 1, false to 0, and
509
* allow other valid integers. */
510
int scenario::get_rtd(const char *ptr, bool start) {
511
if(!strcmp(ptr, (char *)"false"))
514
if(!strcmp(ptr, (char *)"true"))
515
return stats->findRtd("1", start);
517
return stats->findRtd(ptr, start);
521
int scenario::get_counter(const char *ptr, const char *what) {
522
/* Check the name's validity. */
523
if (ptr[0] == '\0') {
524
ERROR("Counter names names may not be empty for %s\n", what);
526
if (strcspn(ptr, "$,") != strlen(ptr)) {
527
ERROR("Counter names may not contain $ or , for %s\n", what);
530
return stats->findCounter(ptr, true);
534
/* Some validation functions. */
536
void scenario::validate_variable_usage() {
537
allocVars->validate();
540
void scenario::validate_txn_usage() {
541
for (unsigned int i = 0; i < transactions.size(); i++) {
542
if(transactions[i].started == 0) {
543
ERROR("Transaction %s is never started!\n", transactions[i].name);
544
} else if(transactions[i].responses == 0) {
545
ERROR("Transaction %s has no responses defined!\n", transactions[i].name);
547
if (transactions[i].isInvite && transactions[i].acks == 0) {
548
ERROR("Transaction %s is an INVITE transaction without an ACK!\n", transactions[i].name);
550
if (!transactions[i].isInvite && (transactions[i].acks > 0)) {
551
ERROR("Transaction %s is a non-INVITE transaction with an ACK!\n", transactions[i].name);
556
/* Apply the next and ontimeout labels according to our map. */
557
void scenario::apply_labels(msgvec v, str_int_map labels) {
558
for (unsigned int i = 0; i < v.size(); i++) {
559
if (v[i]->nextLabel) {
560
str_int_map::iterator label_it = labels.find(v[i]->nextLabel);
561
if (label_it == labels.end()) {
562
ERROR("The label '%s' was not defined (index %d, next attribute)\n", v[i]->nextLabel, i);
564
v[i]->next = label_it->second;
566
if (v[i]->onTimeoutLabel) {
567
str_int_map::iterator label_it = labels.find(v[i]->onTimeoutLabel);
568
if (label_it == labels.end()) {
569
ERROR("The label '%s' was not defined (index %d, ontimeout attribute)\n", v[i]->onTimeoutLabel, i);
571
v[i]->on_timeout = label_it->second;
576
int get_cr_number(char *src)
581
if(*ptr == '\n') res++;
587
char *clean_cdata(char *ptr, int *removed_crlf = NULL) {
590
while((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\n')) ptr++;
592
msg = (char *) malloc(strlen(ptr) + 3);
593
if(!msg) { ERROR("Memory Overflow"); }
596
ptr = msg + strlen(msg);
599
while((ptr >= msg) &&
603
if(*ptr == '\n' && removed_crlf) {
609
if(!strstr(msg, "\n\n")) {
614
ERROR("Empty cdata in xml scenario file");
616
while ((ptr = strstr(msg, "\n "))) {
617
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
619
while ((ptr = strstr(msg, " \n"))) {
620
memmove(ptr, ptr + 1, strlen(ptr));
622
while ((ptr = strstr(msg, "\n\t"))) {
623
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
625
while ((ptr = strstr(msg, "\t\n"))) {
626
memmove(ptr, ptr + 1, strlen(ptr));
634
/********************** Scenario File analyser **********************/
636
void scenario::checkOptionalRecv(char *elem, unsigned int scenario_file_cursor) {
637
if (last_recv_optional) {
638
ERROR("<recv> before <%s> sequence without a mandatory message. Please remove one 'optional=true' (element %d).", elem, scenario_file_cursor);
640
last_recv_optional = false;
643
scenario::scenario(char * filename, int deflt)
646
char *method_list = NULL;
647
unsigned int scenario_file_cursor = 0;
648
int L_content_length = 0 ;
651
last_recv_optional = false;
654
if(!xp_set_xml_buffer_from_file(filename)) {
655
ERROR("Unable to load or parse '%s' xml scenario file", filename);
658
if(!xp_set_xml_buffer_from_string(default_scenario[deflt])) {
659
ERROR("Unable to load default xml scenario file");
664
allocVars = new AllocVariableTable(userVariables);
668
elem = xp_open_element(0);
670
ERROR("No element in xml scenario file");
672
if(strcmp("scenario", elem)) {
673
ERROR("No 'scenario' section in xml scenario file");
676
if(char *ptr = xp_get_value((char *)"name")) {
683
found_timewait = false;
685
scenario_file_cursor = 0;
687
while ((elem = xp_open_element(scenario_file_cursor))) {
689
scenario_file_cursor ++;
691
if(!strcmp(elem, "CallLengthRepartition")) {
692
ptr = xp_get_string("value", "CallLengthRepartition");
693
stats->setRepartitionCallLength(ptr);
695
} else if(!strcmp(elem, "ResponseTimeRepartition")) {
696
ptr = xp_get_string("value", "ResponseTimeRepartition");
697
stats->setRepartitionResponseTime(ptr);
699
} else if(!strcmp(elem, "Global")) {
700
ptr = xp_get_string("variables", "Global");
702
char ** currentTabVarName = NULL;
703
int currentNbVarNames;
705
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
706
for (int i = 0; i < currentNbVarNames; i++) {
707
globalVariables->find(currentTabVarName[i], true);
709
freeStringTable(currentTabVarName, currentNbVarNames);
711
} else if(!strcmp(elem, "User")) {
712
ptr = xp_get_string("variables", "User");
714
char ** currentTabVarName = NULL;
715
int currentNbVarNames;
717
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
718
for (int i = 0; i < currentNbVarNames; i++) {
719
userVariables->find(currentTabVarName[i], true);
721
freeStringTable(currentTabVarName, currentNbVarNames);
723
} else if(!strcmp(elem, "Reference")) {
724
ptr = xp_get_string("variables", "Reference");
726
char ** currentTabVarName = NULL;
727
int currentNbVarNames;
729
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
730
for (int i = 0; i < currentNbVarNames; i++) {
731
int id = allocVars->find(currentTabVarName[i], false);
733
ERROR("Could not reference non-existant variable '%s'", currentTabVarName[i]);
736
freeStringTable(currentTabVarName, currentNbVarNames);
738
} else if(!strcmp(elem, "DefaultMessage")) {
739
char *id = xp_get_string("id", "DefaultMessage");
740
if(!(ptr = xp_get_cdata())) {
741
ERROR("No CDATA in 'send' section of xml scenario file");
743
char *msg = clean_cdata(ptr);
744
set_default_message(id, msg);
746
/* XXX: This should really be per scenario. */
747
} else if(!strcmp(elem, "label")) {
748
ptr = xp_get_string("id", "label");
749
if (labelMap.find(ptr) != labelMap.end()) {
750
ERROR("The label name '%s' is used twice.", ptr);
752
labelMap[ptr] = messages.size();
754
} else if (!strcmp(elem, "init")) {
755
/* We have an init section, which must be full of nops or labels. */
758
while ((initelem = xp_open_element(nop_cursor++))) {
759
if (!strcmp(initelem, "nop")) {
760
/* We should parse this. */
761
message *nopmsg = new message(initmessages.size(), "scenario initialization");
762
initmessages.push_back(nopmsg);
763
nopmsg->M_type = MSG_TYPE_NOP;
764
getCommonAttributes(nopmsg);
765
} else if (!strcmp(initelem, "label")) {
766
/* Add an init label. */
767
ptr = xp_get_value((char *)"id");
768
if (initLabelMap.find(ptr) != initLabelMap.end()) {
769
ERROR("The label name '%s' is used twice.", ptr);
771
initLabelMap[ptr] = initmessages.size();
773
ERROR("Invalid element in an init stanza: '%s'", initelem);
777
} else { /** Message Case */
778
if (found_timewait) {
779
ERROR("<timewait> can only be the last message in a scenario!\n");
781
message *curmsg = new message(messages.size(), name ? name : "unknown scenario");
782
messages.push_back(curmsg);
784
if(!strcmp(elem, "send")) {
785
checkOptionalRecv(elem, scenario_file_cursor);
786
curmsg->M_type = MSG_TYPE_SEND;
787
/* Sent messages descriptions */
788
if(!(ptr = xp_get_cdata())) {
789
ERROR("No CDATA in 'send' section of xml scenario file");
792
int removed_clrf = 0;
793
char * msg = clean_cdata(ptr, &removed_clrf);
795
L_content_length = xp_get_content_length(msg);
796
switch (L_content_length) {
798
// the msg does not contain content-length field
801
curmsg -> content_length_flag =
802
message::ContentLengthValueZero; // Initialize to No present
805
curmsg -> content_length_flag =
806
message::ContentLengthValueNoZero; // Initialize to No present
810
if((msg[strlen(msg) - 1] != '\n') && (removed_clrf)) {
815
curmsg -> send_scheme = new SendingMessage(this, msg);
818
// If this is a request we are sending, then store our transaction/method matching information.
819
if (!curmsg->send_scheme->isResponse()) {
820
char *method = curmsg->send_scheme->getMethod();
821
bool isInvite = !strcmp(method, "INVITE");
822
bool isAck = !strcmp(method, "ACK");
824
if ((ptr = xp_get_value("start_txn"))) {
826
ERROR("An ACK message can not start a transaction!");
828
curmsg->start_txn = get_txn(ptr, "start transaction", true, isInvite, false);
829
} else if ((ptr = xp_get_value("ack_txn"))) {
831
ERROR("The ack_txn attribute is valid only for ACK messages!");
833
curmsg->ack_txn = get_txn(ptr, "ack transaction", false, false, true);
835
int len = method_list ? strlen(method_list) : 0;
836
method_list = (char *)realloc(method_list, len + strlen(method) + 1);
838
ERROR_NO("Out of memory allocating method_list!");
840
strcpy(method_list + len, method);
843
if ((ptr = xp_get_value("start_txn"))) {
844
ERROR("Responses can not start a transaction");
846
if ((ptr = xp_get_value("ack_txn"))) {
847
ERROR("Responses can not ACK a transaction");
851
if ((ptr = xp_get_value("response_txn"))) {
852
ERROR("response_txn can only be used for recieved messages.");
855
curmsg -> retrans_delay = xp_get_long("retrans", "retransmission timer", 0);
856
curmsg -> timeout = xp_get_long("timeout", "message send timeout", 0);
857
} else if(!strcmp(elem, (char *)"recv")) {
858
curmsg->M_type = MSG_TYPE_RECV;
859
/* Received messages descriptions */
860
if((ptr = xp_get_value((char *)"response"))) {
861
curmsg ->recv_response = get_long(ptr, "response code");
863
curmsg->recv_response_for_cseq_method_list = strdup(method_list);
865
if ((ptr = xp_get_value("response_txn"))) {
866
curmsg->response_txn = get_txn(ptr, "transaction response", false, false, false);
870
if((ptr = xp_get_value((char *)"request"))) {
871
curmsg -> recv_request = strdup(ptr);
872
if ((ptr = xp_get_value("response_txn"))) {
873
ERROR("response_txn can only be used for recieved responses.");
877
curmsg->optional = xp_get_optional("optional", "recv");
878
last_recv_optional = curmsg->optional;
879
curmsg->advance_state = xp_get_bool("advance_state", "recv", true);
880
if (!curmsg->advance_state && curmsg->optional == OPTIONAL_FALSE) {
881
ERROR("advance_state is allowed only for optional messages (index = %d)\n", messages.size() - 1);
884
if (0 != (ptr = xp_get_value((char *)"regexp_match"))) {
885
if(!strcmp(ptr, "true")) {
886
curmsg -> regexp_match = 1;
890
curmsg->timeout = xp_get_long("timeout", "message timeout", 0);
892
/* record the route set */
893
/* TODO disallow optional and rrs to coexist? */
894
if((ptr = xp_get_value((char *)"rrs"))) {
895
curmsg -> bShouldRecordRoutes = get_bool(ptr, "record route set");
898
/* record the authentication credentials */
899
if((ptr = xp_get_value((char *)"auth"))) {
900
bool temp = get_bool(ptr, "message authentication");
902
curmsg -> bShouldAuthenticate = temp;
905
ERROR("Authentication requires OpenSSL support!");
909
} else if(!strcmp(elem, "pause") || !strcmp(elem, "timewait")) {
910
checkOptionalRecv(elem, scenario_file_cursor);
911
curmsg->M_type = MSG_TYPE_PAUSE;
912
if (!strcmp(elem, "timewait")) {
913
curmsg->timewait = true;
914
found_timewait = true;
918
if ((var = xp_get_var("variable", "pause", -1)) != -1) {
919
curmsg->pause_variable = var;
921
CSample *distribution = parse_distribution(true);
923
bool sanity_check = xp_get_bool("sanity_check", "pause", true);
925
double pause_duration = distribution->cdfInv(0.99);
926
if (sanity_check && (pause_duration > INT_MAX)) {
927
char percentile[100];
930
distribution->timeDescr(desc, sizeof(desc));
931
time_string(pause_duration, percentile, sizeof(percentile));
933
ERROR("The distribution %s has a 99th percentile of %s, which is larger than INT_MAX. You should chose different parameters.", desc, percentile);
936
curmsg->pause_distribution = distribution;
937
/* Update scenario duration with max duration */
938
duration += (int)pause_duration;
941
else if(!strcmp(elem, "nop")) {
942
checkOptionalRecv(elem, scenario_file_cursor);
943
/* Does nothing at SIP level. This message type can be used to handle
944
* actions, increment counters, or for RTDs. */
945
curmsg->M_type = MSG_TYPE_NOP;
947
else if(!strcmp(elem, "recvCmd")) {
948
curmsg->M_type = MSG_TYPE_RECVCMD;
949
curmsg->optional = xp_get_optional("optional", "recv");
950
last_recv_optional = curmsg->optional;
952
/* 3pcc extended mode */
953
if((ptr = xp_get_value((char *)"src"))) {
954
curmsg ->peer_src = strdup(ptr);
955
} else if (extendedTwinSippMode) {
956
ERROR("You must specify a 'src' for recvCmd when using extended 3pcc mode!");
958
} else if(!strcmp(elem, "sendCmd")) {
959
checkOptionalRecv(elem, scenario_file_cursor);
960
curmsg->M_type = MSG_TYPE_SENDCMD;
961
/* Sent messages descriptions */
963
/* 3pcc extended mode */
964
if((ptr = xp_get_value((char *)"dest"))) {
966
curmsg ->peer_dest = peer ;
967
peer_map::iterator peer_it;
968
peer_it = peers.find(peer_map::key_type(peer));
969
if(peer_it == peers.end()) /* the peer (slave or master)
970
has not been added in the map
971
(first occurence in the scenario) */
974
infos.peer_socket = 0;
975
strcpy(infos.peer_host, get_peer_addr(peer));
976
peers[std::string(peer)] = infos;
978
} else if (extendedTwinSippMode) {
979
ERROR("You must specify a 'dest' for sendCmd with extended 3pcc mode!");
982
if(!(ptr = xp_get_cdata())) {
983
ERROR("No CDATA in 'sendCmd' section of xml scenario file");
985
char *msg = clean_cdata(ptr);
987
curmsg -> M_sendCmdData = new SendingMessage(this, msg, true /* skip sanity */);
991
ERROR("Unknown element '%s' in xml scenario file", elem);
994
getCommonAttributes(curmsg);
995
} /** end * Message case */
1001
str_int_map::iterator label_it = labelMap.find("_unexp.main");
1002
if (label_it != labelMap.end()) {
1003
unexpected_jump = label_it->second;
1005
unexpected_jump = -1;
1007
retaddr = find_var("_unexp.retaddr", "unexpected return address");
1008
pausedaddr = find_var("_unexp.pausedaddr", "unexpected paused until");
1010
/* Patch up the labels. */
1011
apply_labels(messages, labelMap);
1012
apply_labels(initmessages, initLabelMap);
1014
/* Some post-scenario loading validation. */
1015
stats->validateRtds();
1017
/* Make sure that all variables are used more than once. */
1018
validate_variable_usage();
1020
/* Make sure that all started transactions have responses, and vice versa. */
1021
validate_txn_usage();
1023
if (messages.size() == 0) {
1024
ERROR("Did not find any messages inside of scenario!");
1028
void scenario::runInit() {
1030
if (initmessages.size() > 0) {
1031
initcall = new call(main_scenario, NULL, NULL, "///main-init", 0, false, false, true);
1036
void clear_int_str(int_str_map m) {
1037
for(int_str_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1043
void clear_str_int(str_int_map m) {
1044
for(str_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1049
void clear_int_int(int_int_map m) {
1050
for(int_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1055
scenario::~scenario() {
1056
for (msgvec::iterator i = messages.begin(); i != messages.end(); i++) {
1063
allocVars->putTable();
1066
for (unsigned int i = 0; i < transactions.size(); i++) {
1067
free(transactions[i].name);
1069
transactions.clear();
1071
clear_str_int(labelMap);
1072
clear_str_int(initLabelMap);
1073
clear_str_int(txnMap);
1076
CSample *parse_distribution(bool oldstyle = false) {
1077
CSample *distribution;
1081
if(!(distname = xp_get_value("distribution"))) {
1083
ERROR("statistically distributed actions or pauses requires 'distribution' parameter");
1085
if ((ptr = xp_get_value("normal"))) {
1086
distname = "normal";
1087
} else if ((ptr = xp_get_value("exponential"))) {
1088
distname = "exponential";
1089
} else if ((ptr = xp_get_value("lognormal"))) {
1090
distname = "lognormal";
1091
} else if ((ptr = xp_get_value("weibull"))) {
1092
distname = "weibull";
1093
} else if ((ptr = xp_get_value("pareto"))) {
1094
distname = "pareto";
1095
} else if ((ptr = xp_get_value("gamma"))) {
1097
} else if ((ptr = xp_get_value("min"))) {
1098
distname = "uniform";
1099
} else if ((ptr = xp_get_value("max"))) {
1100
distname = "uniform";
1101
} else if ((ptr = xp_get_value("milliseconds"))) {
1102
double val = get_double(ptr, "Pause milliseconds");
1103
return new CFixed(val);
1105
return new CDefaultPause();
1109
if (!strcmp(distname, "fixed")) {
1110
double value = xp_get_double("value", "Fixed distribution");
1111
distribution = new CFixed(value);
1112
} else if (!strcmp(distname, "uniform")) {
1113
double min = xp_get_double("min", "Uniform distribution");
1114
double max = xp_get_double("max", "Uniform distribution");
1115
distribution = new CUniform(min, max);
1116
} else if (!strcmp(distname, "normal")) {
1117
double mean = xp_get_double("mean", "Normal distribution");
1118
double stdev = xp_get_double("stdev", "Normal distribution");
1119
distribution = new CNormal(mean, stdev);
1120
} else if (!strcmp(distname, "lognormal")) {
1121
double mean = xp_get_double("mean", "Lognormal distribution");
1122
double stdev = xp_get_double("stdev", "Lognormal distribution");
1123
distribution = new CLogNormal(mean, stdev);
1124
} else if (!strcmp(distname, "exponential")) {
1125
double mean = xp_get_double("mean", "Exponential distribution");
1126
distribution = new CExponential(mean);
1127
} else if (!strcmp(distname, "weibull")) {
1128
double lambda = xp_get_double("lambda", "Weibull distribution");
1129
double k = xp_get_double("k", "Weibull distribution");
1130
distribution = new CWeibull(lambda, k);
1131
} else if (!strcmp(distname, "pareto")) {
1132
double k = xp_get_double("k", "Pareto distribution");
1133
double xsubm = xp_get_double("x_m", "Pareto distribution");
1134
distribution = new CPareto(k, xsubm);
1135
} else if (!strcmp(distname, "gpareto")) {
1136
double shape = xp_get_double("shape", "Generalized Pareto distribution");
1137
double scale = xp_get_double("scale", "Generalized Pareto distribution");
1138
double location = xp_get_double("location", "Generalized Pareto distribution");
1139
distribution = new CGPareto(shape, scale, location);
1140
} else if (!strcmp(distname, "gamma")) {
1141
double k = xp_get_double("k", "Gamma distribution");
1142
double theta = xp_get_double("theta", "Gamma distribution");
1143
distribution = new CGamma(k, theta);
1144
} else if (!strcmp(distname, "negbin")) {
1145
double n = xp_get_double("n", "Negative Binomial distribution");
1146
double p = xp_get_double("p", "Negative Binomial distribution");
1147
distribution = new CNegBin(n, p);
1149
ERROR("Unknown distribution: %s\n", ptr);
1152
return distribution;
1157
/* 3pcc extended mode:
1158
get the correspondances between
1159
slave and master names and their
1162
void parse_slave_cfg()
1165
char line[MAX_PEER_SIZE];
1170
f = fopen(slave_cfg_file, "r");
1172
while (fgets(line, MAX_PEER_SIZE, f) != NULL)
1174
if((temp_peer = strtok(line, ";"))) {
1175
if((peer_host = (char *) malloc(MAX_PEER_SIZE))){
1176
if((temp_host = strtok(NULL, ";"))){
1177
strcpy(peer_host, temp_host);
1178
peer_addrs[std::string(temp_peer)] = peer_host;
1181
ERROR("Cannot allocate memory!\n");
1186
ERROR("Can not open slave_cfg file %s\n", slave_cfg_file);
1191
// Determine in which mode the sipp tool has been
1192
// launched (client, server, 3pcc client, 3pcc server, 3pcc extended master or slave)
1193
void scenario::computeSippMode()
1195
bool isRecvCmdFound = false;
1196
bool isSendCmdFound = false;
1200
thirdPartyMode = MODE_3PCC_NONE;
1202
assert(messages.size() > 0);
1204
for(unsigned int i=0; i<messages.size(); i++)
1206
switch(messages[i]->M_type)
1208
case MSG_TYPE_PAUSE:
1210
/* Allow pauses or nops to go first. */
1213
if (sendMode == -1) {
1214
sendMode = MODE_CLIENT;
1216
if (creationMode == -1) {
1217
creationMode = MODE_CLIENT;
1222
if (sendMode == -1) {
1223
sendMode = MODE_SERVER;
1225
if (creationMode == -1) {
1226
creationMode = MODE_SERVER;
1229
case MSG_TYPE_SENDCMD:
1230
isSendCmdFound = true;
1231
if (creationMode == -1) {
1232
creationMode = MODE_CLIENT;
1234
if(!isRecvCmdFound) {
1235
if (creationMode == MODE_SERVER) {
1237
* If it is a server already, then start it in
1238
* 3PCC A passive mode
1241
thirdPartyMode = MODE_3PCC_A_PASSIVE;
1242
}else if (extendedTwinSippMode){
1243
thirdPartyMode = MODE_MASTER_PASSIVE;
1247
thirdPartyMode = MODE_3PCC_CONTROLLER_A;
1248
}else if (extendedTwinSippMode){
1249
thirdPartyMode = MODE_MASTER;
1252
if((thirdPartyMode == MODE_MASTER_PASSIVE || thirdPartyMode == MODE_MASTER) && !master_name){
1253
ERROR("Inconsistency between command line and scenario: master scenario but -master option not set\n");
1255
if(!twinSippMode && !extendedTwinSippMode)
1256
ERROR("sendCmd message found in scenario but no twin sipp"
1257
" address has been passed! Use -3pcc option or 3pcc extended mode.\n");
1261
case MSG_TYPE_RECVCMD:
1262
if (creationMode == -1) {
1263
creationMode = MODE_SERVER;
1265
isRecvCmdFound = true;
1269
thirdPartyMode = MODE_3PCC_CONTROLLER_B;
1270
} else if(extendedTwinSippMode){
1271
thirdPartyMode = MODE_SLAVE;
1273
ERROR("Inconsistency between command line and scenario: slave scenario but -slave option not set\n");
1275
thirdPartyMode = MODE_SLAVE;
1278
if(!twinSippMode && !extendedTwinSippMode)
1279
ERROR("recvCmd message found in scenario but no "
1280
"twin sipp address has been passed! Use "
1288
if(creationMode == -1)
1289
ERROR("Unable to determine creation mode of the tool (server, client)\n");
1291
ERROR("Unable to determine send mode of the tool (server, client)\n");
1294
void scenario::handle_rhs(CAction *tmpAction, char *what) {
1295
if (xp_get_value("value")) {
1296
tmpAction->setDoubleValue(xp_get_double("value", what));
1297
if (xp_get_value("variable")) {
1298
ERROR("Value and variable are mutually exclusive for %s action!", what);
1300
} else if (xp_get_value("variable")) {
1301
tmpAction->setVarInId(xp_get_var("variable", what));
1302
if (xp_get_value("value")) {
1303
ERROR("Value and variable are mutually exclusive for %s action!", what);
1306
ERROR("No value or variable defined for %s action!", what);
1310
void scenario::handle_arithmetic(CAction *tmpAction, char *what) {
1311
tmpAction->setVarId(xp_get_var("assign_to", what));
1312
handle_rhs(tmpAction, what);
1315
void scenario::parseAction(CActions *actions) {
1317
unsigned int recvScenarioLen = 0;
1318
char * currentRegExp = NULL;
1319
char * buffer = NULL;
1320
char ** currentTabVarName = NULL;
1321
int currentNbVarNames;
1323
int sub_currentNbVarId;
1325
while((actionElem = xp_open_element(recvScenarioLen))) {
1326
CAction *tmpAction = new CAction(this);
1328
if(!strcmp(actionElem, "ereg")) {
1329
ptr = xp_get_string("regexp", "ereg");
1331
// keeping regexp expression in memory
1332
if(currentRegExp != NULL)
1333
delete[] currentRegExp;
1334
currentRegExp = new char[strlen(ptr)+1];
1335
buffer = new char[strlen(ptr)+1];
1336
xp_replace(ptr, buffer, "<", "<");
1337
xp_replace(buffer, currentRegExp, ">", ">");
1340
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_REGEXP);
1342
// warning - although these are detected for both msg and hdr
1343
// they are only implemented for search_in="hdr"
1344
tmpAction->setCaseIndep(xp_get_bool("case_indep", "ereg", false));
1345
tmpAction->setHeadersOnly(xp_get_bool("start_line", "ereg", false));
1348
if ( 0 != ( ptr = xp_get_value((char *)"search_in") ) ) {
1349
tmpAction->setOccurence(1);
1351
if ( 0 == strcmp(ptr, (char *)"msg") ) {
1352
tmpAction->setLookingPlace(CAction::E_LP_MSG);
1353
tmpAction->setLookingChar (NULL);
1354
} else if ( 0 == strcmp(ptr, (char *)"body") ) {
1355
tmpAction->setLookingPlace(CAction::E_LP_BODY);
1356
tmpAction->setLookingChar (NULL);
1357
} else if (!strcmp(ptr, (char *)"var")) {
1358
tmpAction->setVarInId(xp_get_var("variable", "ereg"));
1359
tmpAction->setLookingPlace(CAction::E_LP_VAR);
1360
} else if (!strcmp(ptr, (char *)"hdr")) {
1361
ptr = xp_get_value((char *)"header");
1362
if (!ptr || !strlen(ptr)) {
1363
ERROR("search_in=\"hdr\" requires header field");
1365
tmpAction->setLookingPlace(CAction::E_LP_HDR);
1366
tmpAction->setLookingChar(ptr);
1367
if (0 != (ptr = xp_get_value((char *)"occurence"))) {
1368
tmpAction->setOccurence (atol(ptr));
1370
if (0 != (ptr = xp_get_value((char *)"occurrence"))) {
1371
tmpAction->setOccurence (atol(ptr));
1374
ERROR("Unknown search_in value %s", ptr);
1377
tmpAction->setLookingPlace(CAction::E_LP_MSG);
1378
tmpAction->setLookingChar(NULL);
1379
} // end if-else search_in
1381
if (xp_get_value("check_it")) {
1382
tmpAction->setCheckIt(xp_get_bool("check_it", "ereg", false));
1383
if (xp_get_value("check_it_inverse")) {
1384
ERROR("Can not have both check_it and check_it_inverse for ereg!");
1387
tmpAction->setCheckItInverse(xp_get_bool("check_it_inverse", "ereg", false));
1390
if (!(ptr = xp_get_value((char *) "assign_to"))) {
1391
ERROR("assign_to value is missing");
1394
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
1396
int varId = get_var(currentTabVarName[0], "assign_to");
1397
tmpAction->setVarId(varId);
1399
tmpAction->setRegExp(currentRegExp);
1400
if (currentNbVarNames > 1 ) {
1401
sub_currentNbVarId = currentNbVarNames - 1 ;
1402
tmpAction->setNbSubVarId(sub_currentNbVarId);
1404
for(int i=1; i<= sub_currentNbVarId; i++) {
1405
int varId = get_var(currentTabVarName[i], "sub expression assign_to");
1406
tmpAction->setSubVarId(varId);
1410
freeStringTable(currentTabVarName, currentNbVarNames);
1412
if(currentRegExp != NULL) {
1413
delete[] currentRegExp;
1415
currentRegExp = NULL;
1416
} /* end !strcmp(actionElem, "ereg") */ else if(!strcmp(actionElem, "log")) {
1417
tmpAction->setMessage(xp_get_string("message", "log"));
1418
tmpAction->setActionType(CAction::E_AT_LOG_TO_FILE);
1419
} else if(!strcmp(actionElem, "warning")) {
1420
tmpAction->setMessage(xp_get_string("message", "warning"));
1421
tmpAction->setActionType(CAction::E_AT_LOG_WARNING);
1422
} else if(!strcmp(actionElem, "error")) {
1423
tmpAction->setMessage(xp_get_string("message", "error"));
1424
tmpAction->setActionType(CAction::E_AT_LOG_ERROR);
1425
} else if(!strcmp(actionElem, "assign")) {
1426
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_VALUE);
1427
handle_arithmetic(tmpAction, "assign");
1428
} else if(!strcmp(actionElem, "assignstr")) {
1429
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_STRING);
1430
tmpAction->setVarId(xp_get_var("assign_to", "assignstr"));
1431
tmpAction->setMessage(xp_get_string("value", "assignstr"));
1432
} else if(!strcmp(actionElem, "gettimeofday")) {
1433
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_GETTIMEOFDAY);
1435
if (!(ptr = xp_get_value((char *) "assign_to"))) {
1436
ERROR("assign_to value is missing");
1438
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
1439
if (currentNbVarNames != 2 ) {
1440
ERROR("The gettimeofday action requires two output variables!");
1442
tmpAction->setNbSubVarId(1);
1444
int varId = get_var(currentTabVarName[0], "gettimeofday seconds assign_to");
1445
tmpAction->setVarId(varId);
1446
varId = get_var(currentTabVarName[1], "gettimeofday useconds assign_to");
1447
tmpAction->setSubVarId(varId);
1449
freeStringTable(currentTabVarName, currentNbVarNames);
1450
} else if(!strcmp(actionElem, "index")) {
1451
tmpAction->setVarId(xp_get_var("assign_to", "index"));
1452
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_INDEX);
1453
} else if(!strcmp(actionElem, "jump")) {
1454
tmpAction->setActionType(CAction::E_AT_JUMP);
1455
handle_rhs(tmpAction, "jump");
1456
} else if(!strcmp(actionElem, "pauserestore")) {
1457
tmpAction->setActionType(CAction::E_AT_PAUSE_RESTORE);
1458
handle_rhs(tmpAction, "pauserestore");
1459
} else if(!strcmp(actionElem, "add")) {
1460
tmpAction->setActionType(CAction::E_AT_VAR_ADD);
1461
handle_arithmetic(tmpAction, "add");
1462
} else if(!strcmp(actionElem, "subtract")) {
1463
tmpAction->setActionType(CAction::E_AT_VAR_SUBTRACT);
1464
handle_arithmetic(tmpAction, "subtract");
1465
} else if(!strcmp(actionElem, "multiply")) {
1466
tmpAction->setActionType(CAction::E_AT_VAR_MULTIPLY);
1467
handle_arithmetic(tmpAction, "multiply");
1468
} else if(!strcmp(actionElem, "divide")) {
1469
tmpAction->setActionType(CAction::E_AT_VAR_DIVIDE);
1470
handle_arithmetic(tmpAction, "divide");
1471
if (tmpAction->getVarInId() == 0) {
1472
if (tmpAction->getDoubleValue() == 0.0) {
1473
ERROR("divide actions can not have a value of zero!");
1476
} else if(!strcmp(actionElem, "sample")) {
1477
tmpAction->setVarId(xp_get_var("assign_to", "sample"));
1478
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_SAMPLE);
1479
tmpAction->setDistribution(parse_distribution());
1480
} else if(!strcmp(actionElem, "todouble")) {
1481
tmpAction->setActionType(CAction::E_AT_VAR_TO_DOUBLE);
1482
tmpAction->setVarId(xp_get_var("assign_to", "todouble"));
1483
tmpAction->setVarInId(xp_get_var("variable", "todouble"));
1484
} else if(!strcmp(actionElem, "test")) {
1485
tmpAction->setVarId(xp_get_var("assign_to", "test"));
1486
tmpAction->setVarInId(xp_get_var("variable", "test"));
1487
if (xp_get_value("value")) {
1488
tmpAction->setDoubleValue(xp_get_double("value", "test"));
1489
if (xp_get_value("variable2")) {
1490
ERROR("Can not have both a value and a variable2 for test!");
1493
tmpAction->setVarIn2Id(xp_get_var("variable2", "test"));
1495
tmpAction->setActionType(CAction::E_AT_VAR_TEST);
1496
ptr = xp_get_string("compare", "test");
1497
if (!strcmp(ptr, "equal")) {
1498
tmpAction->setComparator(CAction::E_C_EQ);
1499
} else if (!strcmp(ptr, "not_equal")) {
1500
tmpAction->setComparator(CAction::E_C_NE);
1501
} else if (!strcmp(ptr, "greater_than")) {
1502
tmpAction->setComparator(CAction::E_C_GT);
1503
} else if (!strcmp(ptr, "less_than")) {
1504
tmpAction->setComparator(CAction::E_C_LT);
1505
} else if (!strcmp(ptr, "greater_than_equal")) {
1506
tmpAction->setComparator(CAction::E_C_GEQ);
1507
} else if (!strcmp(ptr, "less_than_equal")) {
1508
tmpAction->setComparator(CAction::E_C_LEQ);
1510
ERROR("Invalid 'compare' parameter: %s", ptr);
1513
} else if(!strcmp(actionElem, "verifyauth")) {
1515
tmpAction->setVarId(xp_get_var("assign_to", "verifyauth"));
1516
tmpAction->setMessage(xp_get_string("username", "verifyauth"), 0);
1517
tmpAction->setMessage(xp_get_string("password", "verifyauth"), 1);
1518
tmpAction->setActionType(CAction::E_AT_VERIFY_AUTH);
1520
ERROR("The verifyauth action requires OpenSSL support.");
1522
} else if(!strcmp(actionElem, "lookup")) {
1523
tmpAction->setVarId(xp_get_var("assign_to", "lookup"));
1524
tmpAction->setMessage(xp_get_string("file", "lookup"), 0);
1525
tmpAction->setMessage(xp_get_string("key", "lookup"), 1);
1526
tmpAction->setActionType(CAction::E_AT_LOOKUP);
1527
} else if(!strcmp(actionElem, "insert")) {
1528
tmpAction->setMessage(xp_get_string("file", "insert"), 0);
1529
tmpAction->setMessage(xp_get_string("value", "insert"), 1);
1530
tmpAction->setActionType(CAction::E_AT_INSERT);
1531
} else if(!strcmp(actionElem, "replace")) {
1532
tmpAction->setMessage(xp_get_string("file", "replace"), 0);
1533
tmpAction->setMessage(xp_get_string("line", "replace"), 1);
1534
tmpAction->setMessage(xp_get_string("value", "replace"), 2);
1535
tmpAction->setActionType(CAction::E_AT_REPLACE);
1536
} else if(!strcmp(actionElem, "setdest")) {
1537
tmpAction->setMessage(xp_get_string("host", actionElem), 0);
1538
tmpAction->setMessage(xp_get_string("port", actionElem), 1);
1539
tmpAction->setMessage(xp_get_string("protocol", actionElem), 2);
1540
tmpAction->setActionType(CAction::E_AT_SET_DEST);
1541
} else if(!strcmp(actionElem, "closecon")) {
1542
tmpAction->setActionType(CAction::E_AT_CLOSE_CON);
1543
} else if(!strcmp(actionElem, "strcmp")) {
1544
tmpAction->setVarId(xp_get_var("assign_to", "strcmp"));
1545
tmpAction->setVarInId(xp_get_var("variable", "strcmp"));
1546
if (xp_get_value("value")) {
1547
tmpAction->setStringValue(xp_get_string("value", "strcmp"));
1548
if (xp_get_value("variable2")) {
1549
ERROR("Can not have both a value and a variable2 for strcmp!");
1552
tmpAction->setVarIn2Id(xp_get_var("variable2", "strcmp"));
1554
tmpAction->setActionType(CAction::E_AT_VAR_STRCMP);
1555
} else if(!strcmp(actionElem, "trim")) {
1556
tmpAction->setVarId(xp_get_var("assign_to", "trim"));
1557
tmpAction->setActionType(CAction::E_AT_VAR_TRIM);
1558
} else if(!strcmp(actionElem, "exec")) {
1559
if((ptr = xp_get_value((char *)"command"))) {
1560
tmpAction->setActionType(CAction::E_AT_EXECUTE_CMD);
1561
tmpAction->setMessage(ptr);
1562
} /* end (ptr = xp_get_value("command") */ else if((ptr = xp_get_value((char *)"int_cmd"))) {
1563
CAction::T_IntCmdType type(CAction::E_INTCMD_STOPCALL); /* assume the default */
1565
if (!strcmp(ptr, "stop_now")) {
1566
type = CAction::E_INTCMD_STOP_NOW;
1567
} else if (!strcmp(ptr, "stop_gracefully")) {
1568
type = CAction::E_INTCMD_STOP_ALL;
1569
} else if (!strcmp(ptr, "stop_call")) {
1570
type = CAction::E_INTCMD_STOPCALL;
1573
/* the action is well formed, adding it in the */
1574
/* tmpActionTable */
1575
tmpAction->setActionType(CAction::E_AT_EXEC_INTCMD);
1576
tmpAction->setIntCmd(type);
1578
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
1579
tmpAction->setPcapArgs(ptr);
1580
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_AUDIO);
1582
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
1583
tmpAction->setPcapArgs(ptr);
1584
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_VIDEO);
1587
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
1588
ERROR("play_pcap_audio requires pcap support! Please recompile SIPp");
1589
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
1590
ERROR("play_pcap_video requires pcap support! Please recompile SIPp");
1593
ERROR("illegal <exec> in the scenario\n");
1596
ERROR("Unknown action: %s", actionElem);
1599
/* If the action was not well-formed, there should have already been an
1600
* ERROR declaration, thus it is safe to add it here at the end of the loop. */
1601
actions->setAction(tmpAction);
1608
// Action list for the message indexed by message_index in
1610
void scenario::getActionForThisMessage(message *message)
1614
if(!(actionElem = xp_open_element(0))) {
1617
if(strcmp(actionElem, "action")) {
1621
/* We actually have an action element. */
1622
if(message->M_actions != NULL) {
1623
ERROR("Duplicate action for %s index %d", message->desc, message->index);
1625
message->M_actions = new CActions();
1627
parseAction(message->M_actions);
1631
void scenario::getBookKeeping(message *message) {
1634
if((ptr = xp_get_value((char *)"rtd"))) {
1635
message -> stop_rtd = get_rtd(ptr, false);
1637
if ((ptr = xp_get_value((char *)"repeat_rtd"))) {
1638
if (message -> stop_rtd) {
1639
message-> repeat_rtd = get_bool(ptr, "repeat_rtd");
1641
ERROR("There is a repeat_rtd element without an rtd element");
1645
if((ptr = xp_get_value((char *)"start_rtd"))) {
1646
message -> start_rtd = get_rtd(ptr, true);
1649
if((ptr = xp_get_value((char *)"counter"))) {
1650
message -> counter = get_counter(ptr, "counter");
1654
void scenario::getCommonAttributes(message *message) {
1657
getBookKeeping(message);
1658
getActionForThisMessage(message);
1660
if((ptr = xp_get_value((char *)"lost"))) {
1661
message -> lost = get_double(ptr, "lost percentage");
1665
if((ptr = xp_get_value((char *)"crlf"))) {
1666
message -> crlf = 1;
1669
if (xp_get_value("hiderest")) {
1670
hidedefault = xp_get_bool("hiderest", "hiderest");
1672
message -> hide = xp_get_bool("hide", "hide", hidedefault);
1673
if((ptr = xp_get_value((char *)"display"))) {
1674
message -> display_str = strdup(ptr);
1677
message -> condexec = xp_get_var("condexec", "condexec variable", -1);
1678
message -> condexec_inverse = xp_get_bool("condexec_inverse", "condexec_inverse", false);
1680
if ((ptr = xp_get_value((char *)"next"))) {
1681
if (found_timewait) {
1682
ERROR("next labels are not allowed in <timewait> elements.");
1684
message -> nextLabel = strdup(ptr);
1685
message -> test = xp_get_var("test", "test variable", -1);
1686
if ( 0 != ( ptr = xp_get_value((char *)"chance") ) ) {
1687
float chance = get_double(ptr,"chance");
1688
/* probability of branch to next */
1689
if (( chance < 0.0 ) || (chance > 1.0 )) {
1690
ERROR("Chance %s not in range [0..1]", ptr);
1692
message -> chance = (int)((1.0-chance)*RAND_MAX);
1695
message -> chance = 0; /* always */
1699
if ((ptr = xp_get_value((char *)"ontimeout"))) {
1700
if (found_timewait) {
1701
ERROR("ontimeout labels are not allowed in <timewait> elements.");
1703
message -> onTimeoutLabel = strdup(ptr);
1707
// char* manipulation : create a int[] from a char*
1708
// test first is the char* is formed by int separeted by coma
1709
// and then create the table
1711
int isWellFormed(char * P_listeStr, int * nombre)
1713
char * ptr = P_listeStr;
1718
sizeOf = strlen(P_listeStr);
1719
// getting the number
1722
// is the string well formed ? [0-9] [,]
1724
for(int i=0; i<=sizeOf; i++)
1729
if(isANumber == false)
1755
if(isANumber == false)
1772
int createIntegerTable(char * P_listeStr,
1773
unsigned int ** listeInteger,
1777
char * ptr = P_listeStr;
1778
char * ptr_prev = P_listeStr;
1779
unsigned int current_int;
1782
if(isWellFormed(P_listeStr, sizeOfList) == 1)
1784
(*listeInteger) = new unsigned int[(*sizeOfList)];
1785
while((*ptr) != ('\0'))
1789
sscanf(ptr_prev, "%u", ¤t_int);
1790
if (nb<(*sizeOfList))
1791
(*listeInteger)[nb] = current_int;
1799
sscanf(ptr_prev, "%u", ¤t_int);
1800
if (nb<(*sizeOfList))
1801
(*listeInteger)[nb] = current_int;
1809
int createStringTable(char * inputString, char *** stringList, int *sizeOfList)
1820
char *p = strchr(inputString, ',');
1825
*stringList = (char **)realloc(*stringList, sizeof(char *) * (*sizeOfList + 1));
1826
(*stringList)[*sizeOfList] = strdup(inputString);
1831
while (inputString);
1836
void freeStringTable(char ** stringList, int sizeOfList) {
1837
for (int i = 0; i < sizeOfList; i++) {
1838
free(stringList[i]);
1843
/* These are the names of the scenarios, they must match the default_scenario table. */
1844
char *scenario_table[] = {
1858
int find_scenario(const char *scenario) {
1860
max = sizeof(scenario_table)/sizeof(scenario_table[0]);
1862
for (i = 0; i < max; i++) {
1863
if (!strcmp(scenario_table[i], scenario)) {
1868
ERROR("Invalid default scenario name '%s'.\n", scenario);
1872
// TIP: to integrate an existing XML scenario, use the following sed line:
1873
// cat ../3pcc-controller-B.xml | sed -e 's/\"/\\\"/g' -e 's/\(.*\)/\"\1\\n\"/'
1874
char * default_scenario [] = {
1875
/************* Default_scenario[0] ***************/
1877
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
1878
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
1880
"<!-- This program is free software; you can redistribute it and/or -->\n"
1881
"<!-- modify it under the terms of the GNU General Public License as -->\n"
1882
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
1883
"<!-- License, or (at your option) any later version. -->\n"
1885
"<!-- This program is distributed in the hope that it will be useful, -->\n"
1886
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
1887
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
1888
"<!-- GNU General Public License for more details. -->\n"
1890
"<!-- You should have received a copy of the GNU General Public License -->\n"
1891
"<!-- along with this program; if not, write to the -->\n"
1892
"<!-- Free Software Foundation, Inc., -->\n"
1893
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
1895
"<!-- Sipp default 'uac' scenario. -->\n"
1898
"<scenario name=\"Basic Sipstone UAC\">\n"
1899
" <!-- In client mode (sipp placing calls), the Call-ID MUST be -->\n"
1900
" <!-- generated by sipp. To do so, use [call_id] keyword. -->\n"
1901
" <send retrans=\"500\">\n"
1904
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1905
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1906
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1907
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
1908
" Call-ID: [call_id]\n"
1910
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1911
" Max-Forwards: 70\n"
1912
" Subject: Performance Test\n"
1913
" Content-Type: application/sdp\n"
1914
" Content-Length: [len]\n"
1917
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
1919
" c=IN IP[media_ip_type] [media_ip]\n"
1921
" m=audio [media_port] RTP/AVP 0\n"
1922
" a=rtpmap:0 PCMU/8000\n"
1927
" <recv response=\"100\"\n"
1928
" optional=\"true\">\n"
1931
" <recv response=\"180\" optional=\"true\">\n"
1934
" <recv response=\"183\" optional=\"true\">\n"
1937
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
1938
" <!-- are saved and used for following messages sent. Useful to test -->\n"
1939
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
1940
" <recv response=\"200\" rtd=\"true\">\n"
1943
" <!-- Packet lost can be simulated in any send/recv message by -->\n"
1944
" <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent. -->\n"
1948
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1949
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1950
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1951
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1952
" Call-ID: [call_id]\n"
1954
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1955
" Max-Forwards: 70\n"
1956
" Subject: Performance Test\n"
1957
" Content-Length: 0\n"
1962
" <!-- This delay can be customized by the -d command-line option -->\n"
1963
" <!-- or by adding a 'milliseconds = \"value\"' option here. -->\n"
1966
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
1967
" <send retrans=\"500\">\n"
1970
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1971
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1972
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1973
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1974
" Call-ID: [call_id]\n"
1976
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1977
" Max-Forwards: 70\n"
1978
" Subject: Performance Test\n"
1979
" Content-Length: 0\n"
1984
" <recv response=\"200\" crlf=\"true\">\n"
1987
" <!-- definition of the response time repartition table (unit is ms) -->\n"
1988
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
1990
" <!-- definition of the call length repartition table (unit is ms) -->\n"
1991
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
1997
/************* Default_scenario[1] ***************/
1999
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2000
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2002
"<!-- This program is free software; you can redistribute it and/or -->\n"
2003
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2004
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2005
"<!-- License, or (at your option) any later version. -->\n"
2007
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2008
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2009
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2010
"<!-- GNU General Public License for more details. -->\n"
2012
"<!-- You should have received a copy of the GNU General Public License -->\n"
2013
"<!-- along with this program; if not, write to the -->\n"
2014
"<!-- Free Software Foundation, Inc., -->\n"
2015
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2017
"<!-- Sipp default 'uas' scenario. -->\n"
2020
"<scenario name=\"Basic UAS responder\">\n"
2021
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
2022
" <!-- are saved and used for following messages sent. Useful to test -->\n"
2023
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
2024
" <recv request=\"INVITE\" crlf=\"true\">\n"
2027
" <!-- The '[last_*]' keyword is replaced automatically by the -->\n"
2028
" <!-- specified header if it was present in the last message received -->\n"
2029
" <!-- (except if it was a retransmission). If the header was not -->\n"
2030
" <!-- present or if no message has been received, the '[last_*]' -->\n"
2031
" <!-- keyword is discarded, and all bytes until the end of the line -->\n"
2032
" <!-- are also discarded. -->\n"
2034
" <!-- If the specified header was present several times in the -->\n"
2035
" <!-- message, all occurences are concatenated (CRLF seperated) -->\n"
2036
" <!-- to be used in place of the '[last_*]' keyword. -->\n"
2041
" SIP/2.0 180 Ringing\n"
2044
" [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2045
" [last_Call-ID:]\n"
2047
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2048
" Content-Length: 0\n"
2053
" <send retrans=\"500\">\n"
2059
" [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2060
" [last_Call-ID:]\n"
2062
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2063
" Content-Type: application/sdp\n"
2064
" Content-Length: [len]\n"
2067
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2069
" c=IN IP[media_ip_type] [media_ip]\n"
2071
" m=audio [media_port] RTP/AVP 0\n"
2072
" a=rtpmap:0 PCMU/8000\n"
2077
" <recv request=\"ACK\"\n"
2078
" optional=\"true\"\n"
2083
" <recv request=\"BYE\">\n"
2093
" [last_Call-ID:]\n"
2095
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2096
" Content-Length: 0\n"
2101
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2102
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2103
" <timewait milliseconds=\"4000\"/>\n"
2106
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2107
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2109
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2110
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2115
/************* Default_scenario[2] ***************/
2117
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2118
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2120
"<!-- This program is free software; you can redistribute it and/or -->\n"
2121
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2122
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2123
"<!-- License, or (at your option) any later version. -->\n"
2125
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2126
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2127
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2128
"<!-- GNU General Public License for more details. -->\n"
2130
"<!-- You should have received a copy of the GNU General Public License -->\n"
2131
"<!-- along with this program; if not, write to the -->\n"
2132
"<!-- Free Software Foundation, Inc., -->\n"
2133
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2135
"<!-- Sipp default 'regexp client' scenario. -->\n"
2138
"<scenario name=\"Client with regexp scenario\">\n"
2139
" <send retrans=\"500\">\n"
2142
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2143
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2144
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2145
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2146
" Call-ID: [call_id]\n"
2148
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2149
" Max-Forwards: 70\n"
2150
" Subject: Performance Test\n"
2151
" Content-Type: application/sdp\n"
2152
" Content-Length: [len]\n"
2155
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2157
" c=IN IP[media_ip_type] [media_ip]\n"
2159
" m=audio [media_port] RTP/AVP 0\n"
2160
" a=rtpmap:0 PCMU/8000\n"
2165
" <recv response=\"100\"\n"
2166
" optional=\"true\">\n"
2169
" <recv response=\"180\" optional=\"true\">\n"
2171
" <recv response=\"183\" optional=\"true\">\n"
2174
" <recv response=\"200\" start_rtd=\"true\">\n"
2175
" <!-- Definition of regexp in the action tag. The regexp must follow -->\n"
2176
" <!-- the Posix Extended standard (POSIX 1003.2), see: -->\n"
2178
" <!-- http://www.opengroup.org/onlinepubs/007908799/xbd/re.html -->\n"
2180
" <!-- regexp : Contain the regexp to use for matching the -->\n"
2181
" <!-- received message -->\n"
2182
" <!-- MANDATORY -->\n"
2183
" <!-- search_in : msg (try to match against the entire message) -->\n"
2184
" <!-- : hdr (try to match against a specific SIP header -->\n"
2185
" <!-- (passed in the header tag) -->\n"
2186
" <!-- OPTIONAL - default value : msg -->\n"
2187
" <!-- header : Header to try to match against. -->\n"
2188
" <!-- Only used when the search_in tag is set to hdr -->\n"
2189
" <!-- MANDATORY IF search_in is equal to hdr -->\n"
2190
" <!-- check_it : if set to true, the call is marked as failed if -->\n"
2191
" <!-- the regexp doesn't match. -->\n"
2192
" <!-- OPTIONAL - default value : false -->\n"
2193
" <!-- assign_to : contain the variable id (integer) or a list of -->\n"
2194
" <!-- variable id which will be used to store the -->\n"
2195
" <!-- result of the matching process between the regexp -->\n"
2196
" <!-- and the message. This variable can be re-used at -->\n"
2197
" <!-- a later time in the scenario using '[$n]' syntax -->\n"
2198
" <!-- where n is the variable id. -->\n"
2199
" <!-- MANDATORY -->\n"
2201
" <ereg regexp=\"[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[:][0-9]{1,5}\" \n"
2202
" search_in=\"msg\" \n"
2203
" check_it=\"true\" \n"
2204
" assign_to=\"1\"/>\n"
2205
" <ereg regexp=\".*\" \n"
2206
" search_in=\"hdr\" \n"
2207
" header=\"Contact:\" \n"
2208
" check_it=\"true\" \n"
2209
" assign_to=\"6\"/>\n"
2210
" <ereg regexp=\"o=([[:alnum:]]*) ([[:alnum:]]*) ([[:alnum:]]*)\"\n"
2211
" search_in=\"msg\" \n"
2212
" check_it=\"true\" \n"
2213
" assign_to=\"3,4,5,8\"/>\n"
2219
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2220
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2221
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2222
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2223
" Call-ID: [call_id]\n"
2225
" retrievedIp: [$1]\n"
2226
" retrievedContact:[$6]\n"
2227
" retrievedSdpOrigin:[$3]\n"
2228
" retrievedSdpOrigin-username:[$4]\n"
2229
" retrievedSdpOrigin-session-id:[$5]\n"
2230
" retrievedSdpOrigin-version:[$8]\n"
2231
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2232
" Max-Forwards: 70\n"
2233
" Subject: Performance Test\n"
2234
" Content-Length: 0\n"
2238
" <!-- This delay can be customized by the -d command-line option -->\n"
2239
" <!-- or by adding a 'milliseconds = \"value\"' option here. -->\n"
2240
" <pause milliseconds = \"1000\"/>\n"
2242
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2243
" <send retrans=\"500\">\n"
2246
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2247
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2248
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2249
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2250
" Call-ID: [call_id]\n"
2252
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2253
" Max-Forwards: 70\n"
2254
" Subject: Performance Test\n"
2255
" Content-Length: 0\n"
2260
" <recv response=\"200\" crlf=\"true\" rtd=\"true\">\n"
2263
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2264
" <ResponseTimeRepartition value=\"1000, 1040, 1080, 1120, 1160, 1200\"/>\n"
2266
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2267
" <CallLengthRepartition value=\"1000, 1100, 1200, 1300, 1400\"/>\n"
2272
/************* Default_scenario[3] ***************/
2274
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2275
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2277
"<!-- This program is free software; you can redistribute it and/or -->\n"
2278
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2279
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2280
"<!-- License, or (at your option) any later version. -->\n"
2282
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2283
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2284
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2285
"<!-- GNU General Public License for more details. -->\n"
2287
"<!-- You should have received a copy of the GNU General Public License -->\n"
2288
"<!-- along with this program; if not, write to the -->\n"
2289
"<!-- Free Software Foundation, Inc., -->\n"
2290
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2292
"<!-- 3PCC - Controller - A side -->\n"
2294
"<!-- A Controller B -->\n"
2295
"<!-- |(1) INVITE no SDP | | -->\n"
2296
"<!-- |<==================| | -->\n"
2297
"<!-- |(2) 200 offer1 | | -->\n"
2298
"<!-- |==================>| | -->\n"
2299
"<!-- | |(3) INVITE offer1 | -->\n"
2300
"<!-- | |==================>| -->\n"
2301
"<!-- | |(4) 200 OK answer1 | -->\n"
2302
"<!-- | |<==================| -->\n"
2303
"<!-- | |(5) ACK | -->\n"
2304
"<!-- | |==================>| -->\n"
2305
"<!-- |(6) ACK answer1 | | -->\n"
2306
"<!-- |<==================| | -->\n"
2307
"<!-- |(7) RTP | | -->\n"
2308
"<!-- |.......................................| -->\n"
2311
"<scenario name=\"3PCC Controller - A side\">\n"
2312
" <send retrans=\"500\">\n"
2315
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2316
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2317
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2318
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2319
" Call-ID: [call_id]\n"
2321
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2322
" Max-Forwards: 70\n"
2323
" Subject: Performance Test\n"
2324
" Content-Length: 0\n"
2329
" <recv response=\"100\" optional=\"true\"> </recv>\n"
2330
" <recv response=\"180\" optional=\"true\"> </recv>\n"
2331
" <recv response=\"183\" optional=\"true\"> </recv>\n"
2332
" <recv response=\"200\" crlf=\"true\" start_rtd=\"true\">\n"
2334
" <ereg regexp=\"Content-Type:.*\" \n"
2335
" search_in=\"msg\" \n"
2336
" assign_to=\"1\" /> \n"
2342
" Call-ID: [call_id]\n"
2350
" <ereg regexp=\"Content-Type:.*\" \n"
2351
" search_in=\"msg\" \n"
2352
" assign_to=\"2\" /> \n"
2357
" <send rtd=\"true\">\n"
2360
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2361
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2362
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2363
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2364
" Call-ID: [call_id]\n"
2366
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2367
" Max-Forwards: 70\n"
2368
" Subject: Performance Test\n"
2374
" <pause milliseconds=\"1000\"/>\n"
2376
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2377
" <send retrans=\"500\">\n"
2380
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2381
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2382
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2383
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2384
" Call-ID: [call_id]\n"
2386
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2387
" Max-Forwards: 70\n"
2388
" Subject: Performance Test\n"
2389
" Content-Length: 0\n"
2394
" <recv response=\"200\" crlf=\"true\"> </recv>\n"
2399
/************* Default_scenario[4] ***************/
2401
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2402
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2404
"<!-- This program is free software; you can redistribute it and/or -->\n"
2405
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2406
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2407
"<!-- License, or (at your option) any later version. -->\n"
2409
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2410
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2411
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2412
"<!-- GNU General Public License for more details. -->\n"
2414
"<!-- You should have received a copy of the GNU General Public License -->\n"
2415
"<!-- along with this program; if not, write to the -->\n"
2416
"<!-- Free Software Foundation, Inc., -->\n"
2417
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2419
"<!-- 3PCC - Controller - B side -->\n"
2421
"<!-- A Controller B -->\n"
2422
"<!-- |(1) INVITE no SDP | | -->\n"
2423
"<!-- |<==================| | -->\n"
2424
"<!-- |(2) 200 offer1 | | -->\n"
2425
"<!-- |==================>| | -->\n"
2426
"<!-- | |(3) INVITE offer1 | -->\n"
2427
"<!-- | |==================>| -->\n"
2428
"<!-- | |(4) 200 OK answer1 | -->\n"
2429
"<!-- | |<==================| -->\n"
2430
"<!-- | |(5) ACK | -->\n"
2431
"<!-- | |==================>| -->\n"
2432
"<!-- |(6) ACK answer1 | | -->\n"
2433
"<!-- |<==================| | -->\n"
2434
"<!-- |(7) RTP | | -->\n"
2435
"<!-- |.......................................| -->\n"
2439
"<scenario name=\"3PCC Controller - B side\">\n"
2443
" <ereg regexp=\"Content-Type:.*\" \n"
2444
" search_in=\"msg\" \n"
2445
" assign_to=\"1\" /> \n"
2449
" <send retrans=\"500\">\n"
2452
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2453
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2454
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2455
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2456
" Call-ID: [call_id]\n"
2458
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2459
" Max-Forwards: 70\n"
2460
" Subject: Performance Test\n"
2466
" <recv response=\"100\" optional=\"true\"> </recv>\n"
2467
" <recv response=\"180\" optional=\"true\"> </recv>\n"
2468
" <recv response=\"183\" optional=\"true\"> </recv>\n"
2469
" <recv response=\"200\" crlf=\"true\">\n"
2471
" <ereg regexp=\"Content-Type:.*\" \n"
2472
" search_in=\"msg\" \n"
2473
" assign_to=\"2\" /> \n"
2478
" <send start_rtd=\"true\">\n"
2481
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2482
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2483
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2484
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2485
" Call-ID: [call_id]\n"
2487
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2488
" Max-Forwards: 70\n"
2489
" Subject: Performance Test\n"
2490
" Content-Length: 0\n"
2497
" Call-ID: [call_id]\n"
2503
" <pause milliseconds=\"1000\"/>\n"
2506
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2507
" <send retrans=\"500\" rtd=\"true\">\n"
2510
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2511
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2512
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2513
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2514
" Call-ID: [call_id]\n"
2516
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2517
" Max-Forwards: 70\n"
2518
" Subject: Performance Test\n"
2519
" Content-Length: 0\n"
2524
" <recv response=\"200\" crlf=\"true\">\n"
2531
/************* Default_scenario[5] ***************/
2533
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2534
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2536
"<!-- This program is free software; you can redistribute it and/or -->\n"
2537
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2538
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2539
"<!-- License, or (at your option) any later version. -->\n"
2541
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2542
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2543
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2544
"<!-- GNU General Public License for more details. -->\n"
2546
"<!-- You should have received a copy of the GNU General Public License -->\n"
2547
"<!-- along with this program; if not, write to the -->\n"
2548
"<!-- Free Software Foundation, Inc., -->\n"
2549
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2551
"<!-- 3PCC - A side emulator -->\n"
2553
"<!-- A Controller B -->\n"
2554
"<!-- |(1) INVITE no SDP | | -->\n"
2555
"<!-- |<==================| | -->\n"
2556
"<!-- |(2) 200 offer1 | | -->\n"
2557
"<!-- |==================>| | -->\n"
2558
"<!-- | |(3) INVITE offer1 | -->\n"
2559
"<!-- | |==================>| -->\n"
2560
"<!-- | |(4) 200 OK answer1 | -->\n"
2561
"<!-- | |<==================| -->\n"
2562
"<!-- | |(5) ACK | -->\n"
2563
"<!-- | |==================>| -->\n"
2564
"<!-- |(6) ACK answer1 | | -->\n"
2565
"<!-- |<==================| | -->\n"
2566
"<!-- |(7) RTP | | -->\n"
2567
"<!-- |.......................................| -->\n"
2571
"<scenario name=\"3PCC A side\">\n"
2572
" <recv request=\"INVITE\" crlf=\"true\">\n"
2581
" [last_To:];tag=[pid]SIPpTag05[call_number]\n"
2582
" [last_Call-ID:]\n"
2584
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2585
" Content-Type: application/sdp\n"
2586
" Content-Length: [len]\n"
2589
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2591
" c=IN IP[media_ip_type] [media_ip]\n"
2593
" m=audio [media_port] RTP/AVP 0\n"
2594
" a=rtpmap:0 PCMU/8000\n"
2599
" <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2601
" <!-- RTP flow starts from here! -->\n"
2603
" <recv request=\"BYE\" crlf=\"true\"> </recv>\n"
2612
" [last_Call-ID:]\n"
2614
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2615
" Content-Length: 0\n"
2620
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2621
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2622
" <timewait milliseconds=\"2000\"/>\n"
2627
/************* Default_scenario[6] ***************/
2629
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2630
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2632
"<!-- This program is free software; you can redistribute it and/or -->\n"
2633
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2634
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2635
"<!-- License, or (at your option) any later version. -->\n"
2637
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2638
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2639
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2640
"<!-- GNU General Public License for more details. -->\n"
2642
"<!-- You should have received a copy of the GNU General Public License -->\n"
2643
"<!-- along with this program; if not, write to the -->\n"
2644
"<!-- Free Software Foundation, Inc., -->\n"
2645
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2647
"<!-- 3PCC - B side emulator -->\n"
2649
"<!-- A Controller B -->\n"
2650
"<!-- |(1) INVITE no SDP | | -->\n"
2651
"<!-- |<==================| | -->\n"
2652
"<!-- |(2) 200 offer1 | | -->\n"
2653
"<!-- |==================>| | -->\n"
2654
"<!-- | |(3) INVITE offer1 | -->\n"
2655
"<!-- | |==================>| -->\n"
2656
"<!-- | |(4) 200 OK answer1 | -->\n"
2657
"<!-- | |<==================| -->\n"
2658
"<!-- | |(5) ACK | -->\n"
2659
"<!-- | |==================>| -->\n"
2660
"<!-- |(6) ACK answer1 | | -->\n"
2661
"<!-- |<==================| | -->\n"
2662
"<!-- |(7) RTP | | -->\n"
2663
"<!-- |.......................................| -->\n"
2668
"<scenario name=\"3PCC B side\">\n"
2669
" <recv request=\"INVITE\" crlf=\"true\"> </recv>\n"
2677
" [last_To:];tag=[pid]SIPpTag06[call_number]\n"
2678
" [last_Call-ID:]\n"
2680
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2681
" Content-Type: application/sdp\n"
2682
" Content-Length: [len]\n"
2685
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2687
" c=IN IP[media_ip_type] [media_ip]\n"
2689
" m=audio [media_port] RTP/AVP 0\n"
2690
" a=rtpmap:0 PCMU/8000\n"
2695
" <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2697
" <!-- RTP flow starts from here! -->\n"
2699
" <recv request=\"BYE\"> </recv>\n"
2708
" [last_Call-ID:]\n"
2710
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2711
" Content-Length: 0\n"
2716
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2717
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2718
" <timewait milliseconds=\"2000\"/>\n"
2722
/************* Default_scenario[7] ***************/
2724
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2725
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2727
"<!-- This program is free software; you can redistribute it and/or -->\n"
2728
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2729
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2730
"<!-- License, or (at your option) any later version. -->\n"
2732
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2733
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2734
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2735
"<!-- GNU General Public License for more details. -->\n"
2737
"<!-- You should have received a copy of the GNU General Public License -->\n"
2738
"<!-- along with this program; if not, write to the -->\n"
2739
"<!-- Free Software Foundation, Inc., -->\n"
2740
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2742
"<!-- Sipp default 'branchc' scenario. -->\n"
2745
"<scenario name=\"branch_client\">\n"
2746
" <send retrans=\"500\">\n"
2749
" REGISTER sip:CA.cym.com SIP/2.0\n"
2750
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2751
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07[call_number]\n"
2752
" To: ua1 <sip:ua1@nnl.cym:[local_port]>\n"
2753
" Call-ID: [call_id]\n"
2754
" CSeq: 1 REGISTER\n"
2755
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2756
" Content-Length: 0\n"
2762
" <!-- simple case - just jump over a line -->\n"
2763
" <recv response=\"200\" rtd=\"true\" next=\"5\">\n"
2766
" <recv response=\"200\">\n"
2769
" <label id=\"5\"/>\n"
2771
" <send retrans=\"500\">\n"
2774
" INVITE sip:ua2@CA.cym.com SIP/2.0\n"
2775
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2776
" From: ua[call_number] <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2777
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>\n"
2778
" Call-ID: [call_id]\n"
2780
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2781
" Max-Forwards: 70\n"
2782
" Subject: Performance Test\n"
2783
" Content-Type: application/sdp\n"
2784
" Content-Length: [len]\n"
2787
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2789
" c=IN IP[media_ip_type] [media_ip]\n"
2791
" m=audio [media_port] RTP/AVP 0\n"
2792
" a=rtpmap:0 PCMU/8000\n"
2797
" <recv response=\"100\" optional=\"true\">\n"
2800
" <recv response=\"180\" optional=\"true\">\n"
2803
" <recv response=\"183\" optional=\"true\">\n"
2806
" <!-- Do something different on an optional receive -->\n"
2807
" <recv response=\"403\" optional=\"true\" next=\"1\">\n"
2810
" <recv response=\"200\">\n"
2812
" <ereg regexp=\"ua25\"\n"
2813
" search_in=\"hdr\"\n"
2814
" header=\"From: \"\n"
2815
" assign_to=\"8\"/>\n"
2819
" <!-- set variable 8 above on 25th call, send the ACK but skip the pause for it -->\n"
2820
" <send next=\"1\" test=\"8\">\n"
2823
" ACK sip:ua2@CA.cym.com SIP/2.0\n"
2824
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2825
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2826
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2827
" Call-ID: [call_id]\n"
2829
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2830
" Max-Forwards: 70\n"
2831
" Subject: Performance Test\n"
2832
" Content-Length: 0\n"
2837
" <pause milliseconds=\"5000\"/>\n"
2839
" <label id=\"1\"/>\n"
2841
" <send retrans=\"500\">\n"
2844
" BYE sip:ua2@CA.cym.com SIP/2.0\n"
2845
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2846
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2847
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2848
" Call-ID: [call_id]\n"
2850
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2851
" Max-Forwards: 70\n"
2852
" Subject: Performance Test\n"
2853
" Content-Length: 0\n"
2858
" <recv response=\"200\" crlf=\"true\">\n"
2861
" <pause milliseconds=\"4000\"/>\n"
2863
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2864
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2866
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2867
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2872
/************* Default_scenario[8] ***************/
2874
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2875
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2877
"<!-- This program is free software; you can redistribute it and/or -->\n"
2878
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2879
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2880
"<!-- License, or (at your option) any later version. -->\n"
2882
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2883
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2884
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2885
"<!-- GNU General Public License for more details. -->\n"
2887
"<!-- You should have received a copy of the GNU General Public License -->\n"
2888
"<!-- along with this program; if not, write to the -->\n"
2889
"<!-- Free Software Foundation, Inc., -->\n"
2890
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2892
"<!-- Sipp default 'branchs' scenario. -->\n"
2895
"<scenario name=\"branch_server\">\n"
2896
" <recv request=\"REGISTER\">\n"
2905
" [last_To:];tag=[pid]SIPpTag08[call_number]\n"
2906
" [last_Call-ID:]\n"
2908
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2909
" Content-Length: 0\n"
2915
" <!-- Set variable 3 if the ua is of the form ua2... -->\n"
2916
" <recv request=\"INVITE\" crlf=\"true\">\n"
2918
" <ereg regexp=\"ua2\"\n"
2919
" search_in=\"hdr\"\n"
2920
" header=\"From: \"\n"
2921
" assign_to=\"3\"/>\n"
2925
" <!-- send 180 then trying if variable 3 is set -->\n"
2926
" <send next=\"1\" test=\"3\">\n"
2929
" SIP/2.0 180 Ringing\n"
2932
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2933
" [last_Call-ID:]\n"
2935
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2936
" Content-Length: 0\n"
2941
" <!-- if not, send a 403 error then skip to wait for a BYE -->\n"
2942
" <send next=\"2\">\n"
2945
" SIP/2.0 403 Error\n"
2948
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2949
" [last_Call-ID:]\n"
2951
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2952
" Content-Length: 0\n"
2957
" <label id=\"1\"/>\n"
2962
" SIP/2.0 100 Trying\n"
2965
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2966
" [last_Call-ID:]\n"
2968
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2969
" Content-Length: 0\n"
2974
" <send retrans=\"500\">\n"
2980
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2981
" [last_Call-ID:]\n"
2983
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2984
" Content-Type: application/sdp\n"
2985
" Content-Length: [len]\n"
2988
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2990
" c=IN IP[media_ip_type] [media_ip]\n"
2992
" m=audio [media_port] RTP/AVP 0\n"
2993
" a=rtpmap:0 PCMU/8000\n"
2998
" <recv request=\"ACK\"\n"
2999
" optional=\"true\"\n"
3004
" <label id=\"2\"/>\n"
3006
" <recv request=\"BYE\">\n"
3016
" [last_Call-ID:]\n"
3018
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3019
" Content-Length: 0\n"
3024
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
3025
" <!-- able to retransmit it if we receive the BYE again. -->\n"
3026
" <timewait milliseconds=\"4000\"/>\n"
3028
" <!-- Definition of the response time repartition table (unit is ms) -->\n"
3029
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3031
" <!-- Definition of the call length repartition table (unit is ms) -->\n"
3032
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3037
/* Although this scenario will not work without pcap play enabled, there is no
3038
* harm in including it in the binary anyway, because the user could have
3039
* dumped it and passed it with -sf. */
3041
/************* Default_scenario[9] ***************/
3043
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3044
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3046
"<!-- This program is free software; you can redistribute it and/or -->\n"
3047
"<!-- modify it under the terms of the GNU General Public License as -->\n"
3048
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3049
"<!-- License, or (at your option) any later version. -->\n"
3051
"<!-- This program is distributed in the hope that it will be useful, -->\n"
3052
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
3053
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
3054
"<!-- GNU General Public License for more details. -->\n"
3056
"<!-- You should have received a copy of the GNU General Public License -->\n"
3057
"<!-- along with this program; if not, write to the -->\n"
3058
"<!-- Free Software Foundation, Inc., -->\n"
3059
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
3061
"<!-- Sipp 'uac' scenario with pcap (rtp) play -->\n"
3064
"<scenario name=\"UAC with media\">\n"
3065
" <!-- In client mode (sipp placing calls), the Call-ID MUST be -->\n"
3066
" <!-- generated by sipp. To do so, use [call_id] keyword. -->\n"
3067
" <send retrans=\"500\">\n"
3070
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3071
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3072
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3073
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
3074
" Call-ID: [call_id]\n"
3076
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3077
" Max-Forwards: 70\n"
3078
" Subject: Performance Test\n"
3079
" Content-Type: application/sdp\n"
3080
" Content-Length: [len]\n"
3083
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
3085
" c=IN IP[local_ip_type] [local_ip]\n"
3087
" m=audio [auto_media_port] RTP/AVP 8 101\n"
3088
" a=rtpmap:8 PCMA/8000\n"
3089
" a=rtpmap:101 telephone-event/8000\n"
3090
" a=fmtp:101 0-11,16\n"
3095
" <recv response=\"100\" optional=\"true\">\n"
3098
" <recv response=\"180\" optional=\"true\">\n"
3101
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
3102
" <!-- are saved and used for following messages sent. Useful to test -->\n"
3103
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
3104
" <recv response=\"200\" rtd=\"true\" crlf=\"true\">\n"
3107
" <!-- Packet lost can be simulated in any send/recv message by -->\n"
3108
" <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent. -->\n"
3112
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3113
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3114
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3115
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3116
" Call-ID: [call_id]\n"
3118
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3119
" Max-Forwards: 70\n"
3120
" Subject: Performance Test\n"
3121
" Content-Length: 0\n"
3126
" <!-- Play a pre-recorded PCAP file (RTP stream) -->\n"
3129
" <exec play_pcap_audio=\"pcap/g711a.pcap\"/>\n"
3133
" <!-- Pause 8 seconds, which is approximately the duration of the -->\n"
3134
" <!-- PCAP file -->\n"
3135
" <pause milliseconds=\"8000\"/>\n"
3137
" <!-- Play an out of band DTMF '1' -->\n"
3140
" <exec play_pcap_audio=\"pcap/dtmf_2833_1.pcap\"/>\n"
3144
" <pause milliseconds=\"1000\"/>\n"
3146
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
3147
" <send retrans=\"500\">\n"
3150
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3151
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3152
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3153
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3154
" Call-ID: [call_id]\n"
3156
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3157
" Max-Forwards: 70\n"
3158
" Subject: Performance Test\n"
3159
" Content-Length: 0\n"
3164
" <recv response=\"200\" crlf=\"true\">\n"
3167
" <!-- definition of the response time repartition table (unit is ms) -->\n"
3168
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3170
" <!-- definition of the call length repartition table (unit is ms) -->\n"
3171
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3175
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3176
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3178
"<!-- This program is free software; you can redistribute it and/or -->\n"
3179
"<!-- modify it under the terms of the GNU General Public License as -->\n"
3180
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3181
"<!-- License, or (at your option) any later version. -->\n"
3183
"<!-- This program is distributed in the hope that it will be useful, -->\n"
3184
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
3185
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
3186
"<!-- GNU General Public License for more details. -->\n"
3188
"<!-- You should have received a copy of the GNU General Public License -->\n"
3189
"<!-- along with this program; if not, write to the -->\n"
3190
"<!-- Free Software Foundation, Inc., -->\n"
3191
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
3193
"<!-- Sipp default 'uas' scenario. -->\n"
3196
"<scenario name=\"Out-of-call UAS\">\n"
3197
" <recv request=\".*\" regexp_match=\"true\" />\n"
3205
" [last_Call-ID:]\n"
3207
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3208
" Content-Length: 0\n"
3213
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
3214
" <!-- able to retransmit it if we receive the BYE again. -->\n"
3215
" <timewait milliseconds=\"4000\"/>\n"
3218
" <!-- definition of the response time repartition table (unit is ms) -->\n"
3219
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3221
" <!-- definition of the call length repartition table (unit is ms) -->\n"
3222
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"