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
33
#include <gsl/gsl_rng.h>
34
#include <gsl/gsl_randist.h>
35
#include <gsl/gsl_cdf.h>
38
/************************ Class Constructor *************************/
40
message::message(int index, const char *desc)
44
pause_distribution = NULL;
48
bShouldRecordRoutes = 0;
50
bShouldAuthenticate = 0;
62
regexp_compile = NULL;
74
condexec_inverse = false;
75
chance = 0;/* meaning always */
79
onTimeoutLabel = NULL;
82
/* 3pcc extended mode */
100
M_sendCmdData = NULL;
104
content_length_flag = ContentLengthNoPresent;
106
/* How to match responses to this message. */
110
recv_response_for_cseq_method_list = NULL;
115
if(M_actions != NULL)
118
if(send_scheme != NULL)
121
if(recv_request != NULL)
124
if(regexp_compile != NULL)
125
regfree(regexp_compile);
126
free(regexp_compile);
129
if (pause_distribution) {
130
delete pause_distribution;
133
if(M_sendCmdData != NULL)
134
delete M_sendCmdData;
140
free(recv_response_for_cseq_method_list);
143
/******** Global variables which compose the scenario file **********/
145
scenario *main_scenario;
146
scenario *ooc_scenario;
147
scenario *display_scenario;
149
/* This mode setting refers to whether we open calls autonomously (MODE_CLIENT)
150
* or in response to requests (MODE_SERVER). */
151
int creationMode = MODE_CLIENT;
152
/* Send mode. Do we send to a fixed address or to the last one we got. */
153
int sendMode = MODE_CLIENT;
154
/* This describes what our 3PCC behavior is. */
155
int thirdPartyMode = MODE_3PCC_NONE;
157
/*************** Helper functions for various types *****************/
158
long get_long(const char *ptr, const char *what) {
162
ret = strtol(ptr, &endptr, 0);
164
ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
169
unsigned long long get_long_long(const char *ptr, const char *what) {
171
unsigned long long ret;
173
ret = strtoull(ptr, &endptr, 0);
175
ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
180
/* This function returns a time in milliseconds from a string.
181
* The multiplier is used to convert from the default input type into
182
* milliseconds. For example, for seconds you should use 1000 and for
183
* milliseconds use 1. */
184
long get_time(const char *ptr, const char *what, int multiplier) {
191
if (!isdigit(*ptr)) {
192
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
195
for (i = 0, p = ptr; *p; p++) {
201
if (i == 1) { /* mm:ss */
202
ERROR("%s, \"%s\" mm:ss not implemented yet!\n", what, ptr);
204
else if (i == 2) { /* hh:mm:ss */
205
ERROR("%s, \"%s\" hh:mm:ss not implemented yet!\n", what, ptr);
207
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
210
dret = strtod(ptr, &endptr);
212
if (!strcmp(endptr, "s")) { /* Seconds */
213
ret = (long)(dret * 1000);
214
} else if (!strcmp(endptr, "ms")) { /* Milliseconds. */
216
} else if (!strcmp(endptr, "m")) { /* Minutes. */
217
ret = (long)(dret * 60000);
218
} else if (!strcmp(endptr, "h")) { /* Hours. */
219
ret = (long)(dret * 60 * 60 * 1000);
221
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
224
ret = (long)(dret * multiplier);
229
double get_double(const char *ptr, const char *what) {
233
ret = strtod(ptr, &endptr);
235
ERROR("%s, \"%s\" is not a floating point number!\n", what, ptr);
240
char * xp_get_string(const char *name, const char *what) {
243
if (!(ptr = xp_get_value(name))) {
244
ERROR("%s is missing the required '%s' parameter.", what, name);
250
double xp_get_double(const char *name, const char *what) {
255
if (!(ptr = xp_get_value(name))) {
256
ERROR("%s is missing the required '%s' parameter.", what, name);
258
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
259
sprintf(helptext, "%s '%s' parameter", what, name);
260
val = get_double(ptr, helptext);
266
double xp_get_double(const char *name, const char *what, double defval) {
267
if (!(xp_get_value(name))) {
270
return xp_get_double(name, what);
273
long xp_get_long(const char *name, const char *what) {
278
if (!(ptr = xp_get_value(name))) {
279
ERROR("%s is missing the required '%s' parameter.", what, name);
281
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
282
sprintf(helptext, "%s '%s' parameter", what, name);
283
val = get_long(ptr, helptext);
289
long xp_get_long(const char *name, const char *what, long defval) {
290
if (!(xp_get_value(name))) {
293
return xp_get_long(name, what);
297
double xp_get_bool(const char *name, const char *what) {
302
if (!(ptr = xp_get_value(name))) {
303
ERROR("%s is missing the required '%s' parameter.", what, name);
305
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
306
sprintf(helptext, "%s '%s' parameter", what, name);
307
val = get_bool(ptr, helptext);
313
double xp_get_bool(const char *name, const char *what, bool defval) {
314
if (!(xp_get_value(name))) {
317
return xp_get_bool(name, what);
320
int scenario::get_txn(const char *txnName, const char *what, bool start, bool isInvite, bool isAck) {
321
/* Check the name's validity. */
322
if (txnName[0] == '\0') {
323
ERROR("Variable names may not be empty for %s\n", what);
325
if (strcspn(txnName, "$,") != strlen(txnName)) {
326
ERROR("Variable names may not contain $ or , for %s\n", what);
329
/* If this transaction has already been used, then we have nothing to do. */
330
str_int_map::iterator txn_it = txnMap.find(txnName);
331
if (txn_it != txnMap.end()) {
333
/* We need to fill in the invite field. */
334
transactions[txn_it->second - 1].started++;
336
transactions[txn_it->second - 1].acks++;
338
transactions[txn_it->second - 1].responses++;
340
return txn_it->second;
343
/* Assign this variable the next slot. */
344
struct txnControlInfo transaction;
346
transaction.name = strdup(txnName);
348
transaction.started = 1;
349
transaction.responses = 0;
350
transaction.acks = 0;
351
transaction.isInvite = isInvite;
353
/* Does not start or respond to this txn. */
354
transaction.started = 0;
355
transaction.responses = 0;
356
transaction.acks = 1;
357
transaction.isInvite = false;
359
transaction.started = 0;
360
transaction.responses = 1;
361
transaction.acks = 0;
362
transaction.isInvite = false;
365
transactions.push_back(transaction);
366
int txnNum = transactions.size();
367
txnMap[txnName] = txnNum;
372
int scenario::find_var(const char *varName, const char *what) {
373
return allocVars->find(varName, false);
376
int scenario::get_var(const char *varName, const char *what) {
377
/* Check the name's validity. */
378
if (varName[0] == '\0') {
379
ERROR("Transaction names may not be empty for %s\n", what);
381
if (strcspn(varName, "$,") != strlen(varName)) {
382
ERROR("Transaction names may not contain $ or , for %s\n", what);
385
return allocVars->find(varName, true);
388
int scenario::xp_get_var(const char *name, const char *what) {
391
if (!(ptr = xp_get_value(name))) {
392
ERROR("%s is missing the required '%s' variable parameter.", what, name);
395
return get_var(ptr, what);
398
int xp_get_optional(const char *name, const char *what) {
399
char *ptr = xp_get_value(name);
401
if (!(ptr = xp_get_value(name))) {
402
return OPTIONAL_FALSE;
405
if(!strcmp(ptr, "true")) {
406
return OPTIONAL_TRUE;
407
} else if(!strcmp(ptr, "global")) {
408
return OPTIONAL_GLOBAL;
409
} else if(!strcmp(ptr, "false")) {
410
return OPTIONAL_FALSE;
412
ERROR("Could not understand optional value for %s: %s", what, ptr);
415
return OPTIONAL_FALSE;
419
int scenario::xp_get_var(const char *name, const char *what, int defval) {
422
if (!(ptr = xp_get_value(name))) {
426
return xp_get_var(name, what);
429
bool get_bool(const char *ptr, const char *what) {
433
if (!strcmp(ptr, "true")) {
436
if (!strcmp(ptr, "false")) {
440
ret = strtol(ptr, &endptr, 0);
442
ERROR("%s, \"%s\" is not a valid boolean!\n", what, ptr);
444
return ret ? true : false;
447
/* Pretty print a time. */
448
char *time_string(int ms) {
452
snprintf(tmp, sizeof(tmp), "%dms", ms);
453
} else if (ms < 100000) {
454
snprintf(tmp, sizeof(tmp), "%.1fs", ((float)ms)/1000);
456
snprintf(tmp, sizeof(tmp), "%ds", ms/1000);
462
int time_string(double ms, char *res, int reslen) {
464
/* Less then 10 seconds we represent accurately. */
465
if ((int)(ms + 0.9999) == (int)(ms)) {
466
/* We have an integer, or close enough to it. */
467
return snprintf(res, reslen, "%dms", (int)ms);
470
return snprintf(res, reslen, "%.2lfms", ms);
472
return snprintf(res, reslen, "%.1lfms", ms);
475
} else if (ms < 60000) {
476
/* We round to 100ms for times less than a minute. */
477
return snprintf(res, reslen, "%.1fs", ms/1000);
478
} else if (ms < 60 * 60000) {
479
/* We round to 1s for times more than a minute. */
480
int s = (unsigned int)(ms / 1000);
483
return snprintf(res, reslen, "%d:%02d", m, s);
485
int s = (unsigned int)(ms / 1000);
490
return snprintf(res, reslen, "%d:%02d:%02d", h, m, s);
494
char *double_time_string(double ms) {
498
snprintf(tmp, sizeof(tmp), "%.2lfms", ms);
499
} else if (ms < 10000) {
500
snprintf(tmp, sizeof(tmp), "%.1lfms", ms);
501
} else if (ms < 100000) {
502
snprintf(tmp, sizeof(tmp), "%.1lfs", ms / 1000);
504
snprintf(tmp, sizeof(tmp), "%ds", (int)(ms/1000));
510
/* For backwards compatibility, we assign "true" to slot 1, false to 0, and
511
* allow other valid integers. */
512
int scenario::get_rtd(const char *ptr, bool start) {
513
if(!strcmp(ptr, (char *)"false"))
516
if(!strcmp(ptr, (char *)"true"))
517
return stats->findRtd("1", start);
519
return stats->findRtd(ptr, start);
523
int scenario::get_counter(const char *ptr, const char *what) {
524
/* Check the name's validity. */
525
if (ptr[0] == '\0') {
526
ERROR("Counter names names may not be empty for %s\n", what);
528
if (strcspn(ptr, "$,") != strlen(ptr)) {
529
ERROR("Counter names may not contain $ or , for %s\n", what);
532
return stats->findCounter(ptr, true);
536
/* Some validation functions. */
538
void scenario::validate_variable_usage() {
539
allocVars->validate();
542
void scenario::validate_txn_usage() {
543
for (unsigned int i = 0; i < transactions.size(); i++) {
544
if(transactions[i].started == 0) {
545
ERROR("Transaction %s is never started!\n", transactions[i].name);
546
} else if(transactions[i].responses == 0) {
547
ERROR("Transaction %s has no responses defined!\n", transactions[i].name);
549
if (transactions[i].isInvite && transactions[i].acks == 0) {
550
ERROR("Transaction %s is an INVITE transaction without an ACK!\n", transactions[i].name);
552
if (!transactions[i].isInvite && (transactions[i].acks > 0)) {
553
ERROR("Transaction %s is a non-INVITE transaction with an ACK!\n", transactions[i].name);
558
/* Apply the next and ontimeout labels according to our map. */
559
void scenario::apply_labels(msgvec v, str_int_map labels) {
560
for (unsigned int i = 0; i < v.size(); i++) {
561
if (v[i]->nextLabel) {
562
str_int_map::iterator label_it = labels.find(v[i]->nextLabel);
563
if (label_it == labels.end()) {
564
ERROR("The label '%s' was not defined (index %d, next attribute)\n", v[i]->nextLabel, i);
566
v[i]->next = label_it->second;
568
if (v[i]->onTimeoutLabel) {
569
str_int_map::iterator label_it = labels.find(v[i]->onTimeoutLabel);
570
if (label_it == labels.end()) {
571
ERROR("The label '%s' was not defined (index %d, ontimeout attribute)\n", v[i]->onTimeoutLabel, i);
573
v[i]->on_timeout = label_it->second;
578
int get_cr_number(char *src)
583
if(*ptr == '\n') res++;
589
char *clean_cdata(char *ptr, int *removed_crlf = NULL) {
592
while((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\n')) ptr++;
594
msg = (char *) malloc(strlen(ptr) + 3);
595
if(!msg) { ERROR("Memory Overflow"); }
598
ptr = msg + strlen(msg);
601
while((ptr >= msg) &&
605
if(*ptr == '\n' && removed_crlf) {
611
if(!strstr(msg, "\n\n")) {
616
ERROR("Empty cdata in xml scenario file");
618
while ((ptr = strstr(msg, "\n "))) {
619
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
621
while ((ptr = strstr(msg, " \n"))) {
622
memmove(ptr, ptr + 1, strlen(ptr));
624
while ((ptr = strstr(msg, "\n\t"))) {
625
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
627
while ((ptr = strstr(msg, "\t\n"))) {
628
memmove(ptr, ptr + 1, strlen(ptr));
636
/********************** Scenario File analyser **********************/
638
void scenario::checkOptionalRecv(char *elem, unsigned int scenario_file_cursor) {
639
if (last_recv_optional) {
640
ERROR("<recv> before <%s> sequence without a mandatory message. Please remove one 'optional=true' (element %d).", elem, scenario_file_cursor);
642
last_recv_optional = false;
645
scenario::scenario(char * filename, int deflt)
648
char *method_list = NULL;
649
unsigned int scenario_file_cursor = 0;
650
int L_content_length = 0 ;
653
last_recv_optional = false;
656
if(!xp_set_xml_buffer_from_file(filename)) {
657
ERROR("Unable to load or parse '%s' xml scenario file", filename);
660
if(!xp_set_xml_buffer_from_string(default_scenario[deflt])) {
661
ERROR("Unable to load default xml scenario file");
666
allocVars = new AllocVariableTable(userVariables);
670
elem = xp_open_element(0);
672
ERROR("No element in xml scenario file");
674
if(strcmp("scenario", elem)) {
675
ERROR("No 'scenario' section in xml scenario file");
678
if(char *ptr = xp_get_value((char *)"name")) {
685
found_timewait = false;
687
scenario_file_cursor = 0;
689
while ((elem = xp_open_element(scenario_file_cursor))) {
691
scenario_file_cursor ++;
693
if(!strcmp(elem, "CallLengthRepartition")) {
694
ptr = xp_get_string("value", "CallLengthRepartition");
695
stats->setRepartitionCallLength(ptr);
697
} else if(!strcmp(elem, "ResponseTimeRepartition")) {
698
ptr = xp_get_string("value", "ResponseTimeRepartition");
699
stats->setRepartitionResponseTime(ptr);
701
} else if(!strcmp(elem, "Global")) {
702
ptr = xp_get_string("variables", "Global");
704
char ** currentTabVarName = NULL;
705
int currentNbVarNames;
707
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
708
for (int i = 0; i < currentNbVarNames; i++) {
709
globalVariables->find(currentTabVarName[i], true);
711
freeStringTable(currentTabVarName, currentNbVarNames);
713
} else if(!strcmp(elem, "User")) {
714
ptr = xp_get_string("variables", "User");
716
char ** currentTabVarName = NULL;
717
int currentNbVarNames;
719
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
720
for (int i = 0; i < currentNbVarNames; i++) {
721
userVariables->find(currentTabVarName[i], true);
723
freeStringTable(currentTabVarName, currentNbVarNames);
725
} else if(!strcmp(elem, "Reference")) {
726
ptr = xp_get_string("variables", "Reference");
728
char ** currentTabVarName = NULL;
729
int currentNbVarNames;
731
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
732
for (int i = 0; i < currentNbVarNames; i++) {
733
int id = allocVars->find(currentTabVarName[i], false);
735
ERROR("Could not reference non-existant variable '%s'", currentTabVarName[i]);
738
freeStringTable(currentTabVarName, currentNbVarNames);
740
} else if(!strcmp(elem, "DefaultMessage")) {
741
char *id = xp_get_string("id", "DefaultMessage");
742
if(!(ptr = xp_get_cdata())) {
743
ERROR("No CDATA in 'send' section of xml scenario file");
745
char *msg = clean_cdata(ptr);
746
set_default_message(id, msg);
748
/* XXX: This should really be per scenario. */
749
} else if(!strcmp(elem, "label")) {
750
ptr = xp_get_string("id", "label");
751
if (labelMap.find(ptr) != labelMap.end()) {
752
ERROR("The label name '%s' is used twice.", ptr);
754
labelMap[ptr] = messages.size();
756
} else if (!strcmp(elem, "init")) {
757
/* We have an init section, which must be full of nops or labels. */
760
while ((initelem = xp_open_element(nop_cursor++))) {
761
if (!strcmp(initelem, "nop")) {
762
/* We should parse this. */
763
message *nopmsg = new message(initmessages.size(), "scenario initialization");
764
initmessages.push_back(nopmsg);
765
nopmsg->M_type = MSG_TYPE_NOP;
766
getCommonAttributes(nopmsg);
767
} else if (!strcmp(initelem, "label")) {
768
/* Add an init label. */
769
ptr = xp_get_value((char *)"id");
770
if (initLabelMap.find(ptr) != initLabelMap.end()) {
771
ERROR("The label name '%s' is used twice.", ptr);
773
initLabelMap[ptr] = initmessages.size();
775
ERROR("Invalid element in an init stanza: '%s'", initelem);
779
} else { /** Message Case */
780
if (found_timewait) {
781
ERROR("<timewait> can only be the last message in a scenario!\n");
783
message *curmsg = new message(messages.size(), name ? name : "unknown scenario");
784
messages.push_back(curmsg);
786
if(!strcmp(elem, "send")) {
787
checkOptionalRecv(elem, scenario_file_cursor);
788
curmsg->M_type = MSG_TYPE_SEND;
789
/* Sent messages descriptions */
790
if(!(ptr = xp_get_cdata())) {
791
ERROR("No CDATA in 'send' section of xml scenario file");
794
int removed_clrf = 0;
795
char * msg = clean_cdata(ptr, &removed_clrf);
797
L_content_length = xp_get_content_length(msg);
798
switch (L_content_length) {
800
// the msg does not contain content-length field
803
curmsg -> content_length_flag =
804
message::ContentLengthValueZero; // Initialize to No present
807
curmsg -> content_length_flag =
808
message::ContentLengthValueNoZero; // Initialize to No present
812
if((msg[strlen(msg) - 1] != '\n') && (removed_clrf)) {
817
curmsg -> send_scheme = new SendingMessage(this, msg);
820
// If this is a request we are sending, then store our transaction/method matching information.
821
if (!curmsg->send_scheme->isResponse()) {
822
char *method = curmsg->send_scheme->getMethod();
823
bool isInvite = !strcmp(method, "INVITE");
824
bool isAck = !strcmp(method, "ACK");
826
if ((ptr = xp_get_value("start_txn"))) {
828
ERROR("An ACK message can not start a transaction!");
830
curmsg->start_txn = get_txn(ptr, "start transaction", true, isInvite, false);
831
} else if ((ptr = xp_get_value("ack_txn"))) {
833
ERROR("The ack_txn attribute is valid only for ACK messages!");
835
curmsg->ack_txn = get_txn(ptr, "ack transaction", false, false, true);
837
int len = method_list ? strlen(method_list) : 0;
838
method_list = (char *)realloc(method_list, len + strlen(method) + 1);
840
ERROR_NO("Out of memory allocating method_list!");
842
strcpy(method_list + len, method);
845
if ((ptr = xp_get_value("start_txn"))) {
846
ERROR("Responses can not start a transaction");
848
if ((ptr = xp_get_value("ack_txn"))) {
849
ERROR("Responses can not ACK a transaction");
853
if ((ptr = xp_get_value("response_txn"))) {
854
ERROR("response_txn can only be used for recieved messages.");
857
curmsg -> retrans_delay = xp_get_long("retrans", "retransmission timer", 0);
858
curmsg -> timeout = xp_get_long("timeout", "message send timeout", 0);
859
} else if(!strcmp(elem, (char *)"recv")) {
860
curmsg->M_type = MSG_TYPE_RECV;
861
/* Received messages descriptions */
862
if((ptr = xp_get_value((char *)"response"))) {
863
curmsg ->recv_response = get_long(ptr, "response code");
865
curmsg->recv_response_for_cseq_method_list = strdup(method_list);
867
if ((ptr = xp_get_value("response_txn"))) {
868
curmsg->response_txn = get_txn(ptr, "transaction response", false, false, false);
872
if((ptr = xp_get_value((char *)"request"))) {
873
curmsg -> recv_request = strdup(ptr);
874
if ((ptr = xp_get_value("response_txn"))) {
875
ERROR("response_txn can only be used for recieved responses.");
879
curmsg->optional = xp_get_optional("optional", "recv");
880
last_recv_optional = curmsg->optional;
881
curmsg->advance_state = xp_get_bool("advance_state", "recv", true);
882
if (!curmsg->advance_state && curmsg->optional == OPTIONAL_FALSE) {
883
ERROR("advance_state is allowed only for optional messages (index = %d)\n", messages.size() - 1);
886
if (0 != (ptr = xp_get_value((char *)"regexp_match"))) {
887
if(!strcmp(ptr, "true")) {
888
curmsg -> regexp_match = 1;
892
curmsg->timeout = xp_get_long("timeout", "message timeout", 0);
894
/* record the route set */
895
/* TODO disallow optional and rrs to coexist? */
896
if((ptr = xp_get_value((char *)"rrs"))) {
897
curmsg -> bShouldRecordRoutes = get_bool(ptr, "record route set");
900
/* record the authentication credentials */
901
if((ptr = xp_get_value((char *)"auth"))) {
902
bool temp = get_bool(ptr, "message authentication");
904
curmsg -> bShouldAuthenticate = temp;
907
ERROR("Authentication requires OpenSSL support!");
911
} else if(!strcmp(elem, "pause") || !strcmp(elem, "timewait")) {
912
checkOptionalRecv(elem, scenario_file_cursor);
913
curmsg->M_type = MSG_TYPE_PAUSE;
914
if (!strcmp(elem, "timewait")) {
915
curmsg->timewait = true;
916
found_timewait = true;
920
if ((var = xp_get_var("variable", "pause", -1)) != -1) {
921
curmsg->pause_variable = var;
923
CSample *distribution = parse_distribution(true);
925
bool sanity_check = xp_get_bool("sanity_check", "pause", true);
927
double pause_duration = distribution->cdfInv(0.99);
928
if (sanity_check && (pause_duration > INT_MAX)) {
929
char percentile[100];
932
distribution->timeDescr(desc, sizeof(desc));
933
time_string(pause_duration, percentile, sizeof(percentile));
935
ERROR("The distribution %s has a 99th percentile of %s, which is larger than INT_MAX. You should chose different parameters.", desc, percentile);
938
curmsg->pause_distribution = distribution;
939
/* Update scenario duration with max duration */
940
duration += (int)pause_duration;
943
else if(!strcmp(elem, "nop")) {
944
checkOptionalRecv(elem, scenario_file_cursor);
945
/* Does nothing at SIP level. This message type can be used to handle
946
* actions, increment counters, or for RTDs. */
947
curmsg->M_type = MSG_TYPE_NOP;
949
else if(!strcmp(elem, "recvCmd")) {
950
curmsg->M_type = MSG_TYPE_RECVCMD;
951
curmsg->optional = xp_get_optional("optional", "recv");
952
last_recv_optional = curmsg->optional;
954
/* 3pcc extended mode */
955
if((ptr = xp_get_value((char *)"src"))) {
956
curmsg ->peer_src = strdup(ptr);
957
} else if (extendedTwinSippMode) {
958
ERROR("You must specify a 'src' for recvCmd when using extended 3pcc mode!");
960
} else if(!strcmp(elem, "sendCmd")) {
961
checkOptionalRecv(elem, scenario_file_cursor);
962
curmsg->M_type = MSG_TYPE_SENDCMD;
963
/* Sent messages descriptions */
965
/* 3pcc extended mode */
966
if((ptr = xp_get_value((char *)"dest"))) {
968
curmsg ->peer_dest = peer ;
969
peer_map::iterator peer_it;
970
peer_it = peers.find(peer_map::key_type(peer));
971
if(peer_it == peers.end()) /* the peer (slave or master)
972
has not been added in the map
973
(first occurence in the scenario) */
976
infos.peer_socket = 0;
977
strcpy(infos.peer_host, get_peer_addr(peer));
978
peers[std::string(peer)] = infos;
980
} else if (extendedTwinSippMode) {
981
ERROR("You must specify a 'dest' for sendCmd with extended 3pcc mode!");
984
if(!(ptr = xp_get_cdata())) {
985
ERROR("No CDATA in 'sendCmd' section of xml scenario file");
987
char *msg = clean_cdata(ptr);
989
curmsg -> M_sendCmdData = new SendingMessage(this, msg, true /* skip sanity */);
993
ERROR("Unknown element '%s' in xml scenario file", elem);
996
getCommonAttributes(curmsg);
997
} /** end * Message case */
1003
str_int_map::iterator label_it = labelMap.find("_unexp.main");
1004
if (label_it != labelMap.end()) {
1005
unexpected_jump = label_it->second;
1007
unexpected_jump = -1;
1009
retaddr = find_var("_unexp.retaddr", "unexpected return address");
1010
pausedaddr = find_var("_unexp.pausedaddr", "unexpected paused until");
1012
/* Patch up the labels. */
1013
apply_labels(messages, labelMap);
1014
apply_labels(initmessages, initLabelMap);
1016
/* Some post-scenario loading validation. */
1017
stats->validateRtds();
1019
/* Make sure that all variables are used more than once. */
1020
validate_variable_usage();
1022
/* Make sure that all started transactions have responses, and vice versa. */
1023
validate_txn_usage();
1025
if (messages.size() == 0) {
1026
ERROR("Did not find any messages inside of scenario!");
1030
void scenario::runInit() {
1032
if (initmessages.size() > 0) {
1033
initcall = new call(main_scenario, NULL, NULL, "///main-init", 0, false, false, true);
1038
void clear_int_str(int_str_map m) {
1039
for(int_str_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1045
void clear_str_int(str_int_map m) {
1046
for(str_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1051
void clear_int_int(int_int_map m) {
1052
for(int_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1057
scenario::~scenario() {
1058
for (msgvec::iterator i = messages.begin(); i != messages.end(); i++) {
1065
allocVars->putTable();
1068
for (unsigned int i = 0; i < transactions.size(); i++) {
1069
free(transactions[i].name);
1071
transactions.clear();
1073
clear_str_int(labelMap);
1074
clear_str_int(initLabelMap);
1075
clear_str_int(txnMap);
1078
CSample *parse_distribution(bool oldstyle = false) {
1079
CSample *distribution;
1083
if(!(distname = xp_get_value("distribution"))) {
1085
ERROR("statistically distributed actions or pauses requires 'distribution' parameter");
1087
if ((ptr = xp_get_value("normal"))) {
1088
distname = "normal";
1089
} else if ((ptr = xp_get_value("exponential"))) {
1090
distname = "exponential";
1091
} else if ((ptr = xp_get_value("lognormal"))) {
1092
distname = "lognormal";
1093
} else if ((ptr = xp_get_value("weibull"))) {
1094
distname = "weibull";
1095
} else if ((ptr = xp_get_value("pareto"))) {
1096
distname = "pareto";
1097
} else if ((ptr = xp_get_value("gamma"))) {
1099
} else if ((ptr = xp_get_value("min"))) {
1100
distname = "uniform";
1101
} else if ((ptr = xp_get_value("max"))) {
1102
distname = "uniform";
1103
} else if ((ptr = xp_get_value("milliseconds"))) {
1104
double val = get_double(ptr, "Pause milliseconds");
1105
return new CFixed(val);
1107
return new CDefaultPause();
1111
if (!strcmp(distname, "fixed")) {
1112
double value = xp_get_double("value", "Fixed distribution");
1113
distribution = new CFixed(value);
1114
} else if (!strcmp(distname, "uniform")) {
1115
double min = xp_get_double("min", "Uniform distribution");
1116
double max = xp_get_double("max", "Uniform distribution");
1117
distribution = new CUniform(min, max);
1119
} else if (!strcmp(distname, "normal")) {
1120
double mean = xp_get_double("mean", "Normal distribution");
1121
double stdev = xp_get_double("stdev", "Normal distribution");
1122
distribution = new CNormal(mean, stdev);
1123
} else if (!strcmp(distname, "lognormal")) {
1124
double mean = xp_get_double("mean", "Lognormal distribution");
1125
double stdev = xp_get_double("stdev", "Lognormal distribution");
1126
distribution = new CLogNormal(mean, stdev);
1127
} else if (!strcmp(distname, "exponential")) {
1128
double mean = xp_get_double("mean", "Exponential distribution");
1129
distribution = new CExponential(mean);
1130
} else if (!strcmp(distname, "weibull")) {
1131
double lambda = xp_get_double("lambda", "Weibull distribution");
1132
double k = xp_get_double("k", "Weibull distribution");
1133
distribution = new CWeibull(lambda, k);
1134
} else if (!strcmp(distname, "pareto")) {
1135
double k = xp_get_double("k", "Pareto distribution");
1136
double xsubm = xp_get_double("x_m", "Pareto distribution");
1137
distribution = new CPareto(k, xsubm);
1138
} else if (!strcmp(distname, "gpareto")) {
1139
double shape = xp_get_double("shape", "Generalized Pareto distribution");
1140
double scale = xp_get_double("scale", "Generalized Pareto distribution");
1141
double location = xp_get_double("location", "Generalized Pareto distribution");
1142
distribution = new CGPareto(shape, scale, location);
1143
} else if (!strcmp(distname, "gamma")) {
1144
double k = xp_get_double("k", "Gamma distribution");
1145
double theta = xp_get_double("theta", "Gamma distribution");
1146
distribution = new CGamma(k, theta);
1147
} else if (!strcmp(distname, "negbin")) {
1148
double n = xp_get_double("n", "Negative Binomial distribution");
1149
double p = xp_get_double("p", "Negative Binomial distribution");
1150
distribution = new CNegBin(n, p);
1152
} else if (!strcmp(distname, "normal")
1153
|| !strcmp(distname, "lognormal")
1154
|| !strcmp(distname, "exponential")
1155
|| !strcmp(distname, "pareto")
1156
|| !strcmp(distname, "gamma")
1157
|| !strcmp(distname, "negbin")
1158
|| !strcmp(distname, "weibull")) {
1159
ERROR("The distribution '%s' is only available with GSL.", distname);
1162
ERROR("Unknown distribution: %s\n", ptr);
1165
return distribution;
1170
/* 3pcc extended mode:
1171
get the correspondances between
1172
slave and master names and their
1175
void parse_slave_cfg()
1178
char line[MAX_PEER_SIZE];
1183
f = fopen(slave_cfg_file, "r");
1185
while (fgets(line, MAX_PEER_SIZE, f) != NULL)
1187
if((temp_peer = strtok(line, ";"))) {
1188
if((peer_host = (char *) malloc(MAX_PEER_SIZE))){
1189
if((temp_host = strtok(NULL, ";"))){
1190
strcpy(peer_host, temp_host);
1191
peer_addrs[std::string(temp_peer)] = peer_host;
1194
ERROR("Cannot allocate memory!\n");
1199
ERROR("Can not open slave_cfg file %s\n", slave_cfg_file);
1204
// Determine in which mode the sipp tool has been
1205
// launched (client, server, 3pcc client, 3pcc server, 3pcc extended master or slave)
1206
void scenario::computeSippMode()
1208
bool isRecvCmdFound = false;
1209
bool isSendCmdFound = false;
1213
thirdPartyMode = MODE_3PCC_NONE;
1215
assert(messages.size() > 0);
1217
for(unsigned int i=0; i<messages.size(); i++)
1219
switch(messages[i]->M_type)
1221
case MSG_TYPE_PAUSE:
1223
/* Allow pauses or nops to go first. */
1226
if (sendMode == -1) {
1227
sendMode = MODE_CLIENT;
1229
if (creationMode == -1) {
1230
creationMode = MODE_CLIENT;
1235
if (sendMode == -1) {
1236
sendMode = MODE_SERVER;
1238
if (creationMode == -1) {
1239
creationMode = MODE_SERVER;
1242
case MSG_TYPE_SENDCMD:
1243
isSendCmdFound = true;
1244
if (creationMode == -1) {
1245
creationMode = MODE_CLIENT;
1247
if(!isRecvCmdFound) {
1248
if (creationMode == MODE_SERVER) {
1250
* If it is a server already, then start it in
1251
* 3PCC A passive mode
1254
thirdPartyMode = MODE_3PCC_A_PASSIVE;
1255
}else if (extendedTwinSippMode){
1256
thirdPartyMode = MODE_MASTER_PASSIVE;
1260
thirdPartyMode = MODE_3PCC_CONTROLLER_A;
1261
}else if (extendedTwinSippMode){
1262
thirdPartyMode = MODE_MASTER;
1265
if((thirdPartyMode == MODE_MASTER_PASSIVE || thirdPartyMode == MODE_MASTER) && !master_name){
1266
ERROR("Inconsistency between command line and scenario: master scenario but -master option not set\n");
1268
if(!twinSippMode && !extendedTwinSippMode)
1269
ERROR("sendCmd message found in scenario but no twin sipp"
1270
" address has been passed! Use -3pcc option or 3pcc extended mode.\n");
1274
case MSG_TYPE_RECVCMD:
1275
if (creationMode == -1) {
1276
creationMode = MODE_SERVER;
1278
isRecvCmdFound = true;
1282
thirdPartyMode = MODE_3PCC_CONTROLLER_B;
1283
} else if(extendedTwinSippMode){
1284
thirdPartyMode = MODE_SLAVE;
1286
ERROR("Inconsistency between command line and scenario: slave scenario but -slave option not set\n");
1288
thirdPartyMode = MODE_SLAVE;
1291
if(!twinSippMode && !extendedTwinSippMode)
1292
ERROR("recvCmd message found in scenario but no "
1293
"twin sipp address has been passed! Use "
1301
if(creationMode == -1)
1302
ERROR("Unable to determine creation mode of the tool (server, client)\n");
1304
ERROR("Unable to determine send mode of the tool (server, client)\n");
1307
void scenario::handle_rhs(CAction *tmpAction, char *what) {
1308
if (xp_get_value("value")) {
1309
tmpAction->setDoubleValue(xp_get_double("value", what));
1310
if (xp_get_value("variable")) {
1311
ERROR("Value and variable are mutually exclusive for %s action!", what);
1313
} else if (xp_get_value("variable")) {
1314
tmpAction->setVarInId(xp_get_var("variable", what));
1315
if (xp_get_value("value")) {
1316
ERROR("Value and variable are mutually exclusive for %s action!", what);
1319
ERROR("No value or variable defined for %s action!", what);
1323
void scenario::handle_arithmetic(CAction *tmpAction, char *what) {
1324
tmpAction->setVarId(xp_get_var("assign_to", what));
1325
handle_rhs(tmpAction, what);
1328
void scenario::parseAction(CActions *actions) {
1330
unsigned int recvScenarioLen = 0;
1331
char * currentRegExp = NULL;
1332
char * buffer = NULL;
1333
char ** currentTabVarName = NULL;
1334
int currentNbVarNames;
1336
int sub_currentNbVarId;
1338
while((actionElem = xp_open_element(recvScenarioLen))) {
1339
CAction *tmpAction = new CAction(this);
1341
if(!strcmp(actionElem, "ereg")) {
1342
ptr = xp_get_string("regexp", "ereg");
1344
// keeping regexp expression in memory
1345
if(currentRegExp != NULL)
1346
delete[] currentRegExp;
1347
currentRegExp = new char[strlen(ptr)+1];
1348
buffer = new char[strlen(ptr)+1];
1349
xp_replace(ptr, buffer, "<", "<");
1350
xp_replace(buffer, currentRegExp, ">", ">");
1353
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_REGEXP);
1355
// warning - although these are detected for both msg and hdr
1356
// they are only implemented for search_in="hdr"
1357
tmpAction->setCaseIndep(xp_get_bool("case_indep", "ereg", false));
1358
tmpAction->setHeadersOnly(xp_get_bool("start_line", "ereg", false));
1361
if ( 0 != ( ptr = xp_get_value((char *)"search_in") ) ) {
1362
tmpAction->setOccurence(1);
1364
if ( 0 == strcmp(ptr, (char *)"msg") ) {
1365
tmpAction->setLookingPlace(CAction::E_LP_MSG);
1366
tmpAction->setLookingChar (NULL);
1367
} else if ( 0 == strcmp(ptr, (char *)"body") ) {
1368
tmpAction->setLookingPlace(CAction::E_LP_BODY);
1369
tmpAction->setLookingChar (NULL);
1370
} else if (!strcmp(ptr, (char *)"var")) {
1371
tmpAction->setVarInId(xp_get_var("variable", "ereg"));
1372
tmpAction->setLookingPlace(CAction::E_LP_VAR);
1373
} else if (!strcmp(ptr, (char *)"hdr")) {
1374
ptr = xp_get_value((char *)"header");
1375
if (!ptr || !strlen(ptr)) {
1376
ERROR("search_in=\"hdr\" requires header field");
1378
tmpAction->setLookingPlace(CAction::E_LP_HDR);
1379
tmpAction->setLookingChar(ptr);
1380
if (0 != (ptr = xp_get_value((char *)"occurence"))) {
1381
tmpAction->setOccurence (atol(ptr));
1383
if (0 != (ptr = xp_get_value((char *)"occurrence"))) {
1384
tmpAction->setOccurence (atol(ptr));
1387
ERROR("Unknown search_in value %s", ptr);
1390
tmpAction->setLookingPlace(CAction::E_LP_MSG);
1391
tmpAction->setLookingChar(NULL);
1392
} // end if-else search_in
1394
if (xp_get_value("check_it")) {
1395
tmpAction->setCheckIt(xp_get_bool("check_it", "ereg", false));
1396
if (xp_get_value("check_it_inverse")) {
1397
ERROR("Can not have both check_it and check_it_inverse for ereg!");
1400
tmpAction->setCheckItInverse(xp_get_bool("check_it_inverse", "ereg", false));
1403
if (!(ptr = xp_get_value((char *) "assign_to"))) {
1404
ERROR("assign_to value is missing");
1407
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
1409
int varId = get_var(currentTabVarName[0], "assign_to");
1410
tmpAction->setVarId(varId);
1412
tmpAction->setRegExp(currentRegExp);
1413
if (currentNbVarNames > 1 ) {
1414
sub_currentNbVarId = currentNbVarNames - 1 ;
1415
tmpAction->setNbSubVarId(sub_currentNbVarId);
1417
for(int i=1; i<= sub_currentNbVarId; i++) {
1418
int varId = get_var(currentTabVarName[i], "sub expression assign_to");
1419
tmpAction->setSubVarId(varId);
1423
freeStringTable(currentTabVarName, currentNbVarNames);
1425
if(currentRegExp != NULL) {
1426
delete[] currentRegExp;
1428
currentRegExp = NULL;
1429
} /* end !strcmp(actionElem, "ereg") */ else if(!strcmp(actionElem, "log")) {
1430
tmpAction->setMessage(xp_get_string("message", "log"));
1431
tmpAction->setActionType(CAction::E_AT_LOG_TO_FILE);
1432
} else if(!strcmp(actionElem, "warning")) {
1433
tmpAction->setMessage(xp_get_string("message", "warning"));
1434
tmpAction->setActionType(CAction::E_AT_LOG_WARNING);
1435
} else if(!strcmp(actionElem, "error")) {
1436
tmpAction->setMessage(xp_get_string("message", "error"));
1437
tmpAction->setActionType(CAction::E_AT_LOG_ERROR);
1438
} else if(!strcmp(actionElem, "assign")) {
1439
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_VALUE);
1440
handle_arithmetic(tmpAction, "assign");
1441
} else if(!strcmp(actionElem, "assignstr")) {
1442
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_STRING);
1443
tmpAction->setVarId(xp_get_var("assign_to", "assignstr"));
1444
tmpAction->setMessage(xp_get_string("value", "assignstr"));
1445
} else if(!strcmp(actionElem, "gettimeofday")) {
1446
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_GETTIMEOFDAY);
1448
if (!(ptr = xp_get_value((char *) "assign_to"))) {
1449
ERROR("assign_to value is missing");
1451
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
1452
if (currentNbVarNames != 2 ) {
1453
ERROR("The gettimeofday action requires two output variables!");
1455
tmpAction->setNbSubVarId(1);
1457
int varId = get_var(currentTabVarName[0], "gettimeofday seconds assign_to");
1458
tmpAction->setVarId(varId);
1459
varId = get_var(currentTabVarName[1], "gettimeofday useconds assign_to");
1460
tmpAction->setSubVarId(varId);
1462
freeStringTable(currentTabVarName, currentNbVarNames);
1463
} else if(!strcmp(actionElem, "index")) {
1464
tmpAction->setVarId(xp_get_var("assign_to", "index"));
1465
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_INDEX);
1466
} else if(!strcmp(actionElem, "jump")) {
1467
tmpAction->setActionType(CAction::E_AT_JUMP);
1468
handle_rhs(tmpAction, "jump");
1469
} else if(!strcmp(actionElem, "pauserestore")) {
1470
tmpAction->setActionType(CAction::E_AT_PAUSE_RESTORE);
1471
handle_rhs(tmpAction, "pauserestore");
1472
} else if(!strcmp(actionElem, "add")) {
1473
tmpAction->setActionType(CAction::E_AT_VAR_ADD);
1474
handle_arithmetic(tmpAction, "add");
1475
} else if(!strcmp(actionElem, "subtract")) {
1476
tmpAction->setActionType(CAction::E_AT_VAR_SUBTRACT);
1477
handle_arithmetic(tmpAction, "subtract");
1478
} else if(!strcmp(actionElem, "multiply")) {
1479
tmpAction->setActionType(CAction::E_AT_VAR_MULTIPLY);
1480
handle_arithmetic(tmpAction, "multiply");
1481
} else if(!strcmp(actionElem, "divide")) {
1482
tmpAction->setActionType(CAction::E_AT_VAR_DIVIDE);
1483
handle_arithmetic(tmpAction, "divide");
1484
if (tmpAction->getVarInId() == 0) {
1485
if (tmpAction->getDoubleValue() == 0.0) {
1486
ERROR("divide actions can not have a value of zero!");
1489
} else if(!strcmp(actionElem, "sample")) {
1490
tmpAction->setVarId(xp_get_var("assign_to", "sample"));
1491
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_SAMPLE);
1492
tmpAction->setDistribution(parse_distribution());
1493
} else if(!strcmp(actionElem, "todouble")) {
1494
tmpAction->setActionType(CAction::E_AT_VAR_TO_DOUBLE);
1495
tmpAction->setVarId(xp_get_var("assign_to", "todouble"));
1496
tmpAction->setVarInId(xp_get_var("variable", "todouble"));
1497
} else if(!strcmp(actionElem, "test")) {
1498
tmpAction->setVarId(xp_get_var("assign_to", "test"));
1499
tmpAction->setVarInId(xp_get_var("variable", "test"));
1500
if (xp_get_value("value")) {
1501
tmpAction->setDoubleValue(xp_get_double("value", "test"));
1502
if (xp_get_value("variable2")) {
1503
ERROR("Can not have both a value and a variable2 for test!");
1506
tmpAction->setVarIn2Id(xp_get_var("variable2", "test"));
1508
tmpAction->setActionType(CAction::E_AT_VAR_TEST);
1509
ptr = xp_get_string("compare", "test");
1510
if (!strcmp(ptr, "equal")) {
1511
tmpAction->setComparator(CAction::E_C_EQ);
1512
} else if (!strcmp(ptr, "not_equal")) {
1513
tmpAction->setComparator(CAction::E_C_NE);
1514
} else if (!strcmp(ptr, "greater_than")) {
1515
tmpAction->setComparator(CAction::E_C_GT);
1516
} else if (!strcmp(ptr, "less_than")) {
1517
tmpAction->setComparator(CAction::E_C_LT);
1518
} else if (!strcmp(ptr, "greater_than_equal")) {
1519
tmpAction->setComparator(CAction::E_C_GEQ);
1520
} else if (!strcmp(ptr, "less_than_equal")) {
1521
tmpAction->setComparator(CAction::E_C_LEQ);
1523
ERROR("Invalid 'compare' parameter: %s", ptr);
1526
} else if(!strcmp(actionElem, "verifyauth")) {
1528
tmpAction->setVarId(xp_get_var("assign_to", "verifyauth"));
1529
tmpAction->setMessage(xp_get_string("username", "verifyauth"), 0);
1530
tmpAction->setMessage(xp_get_string("password", "verifyauth"), 1);
1531
tmpAction->setActionType(CAction::E_AT_VERIFY_AUTH);
1533
ERROR("The verifyauth action requires OpenSSL support.");
1535
} else if(!strcmp(actionElem, "lookup")) {
1536
tmpAction->setVarId(xp_get_var("assign_to", "lookup"));
1537
tmpAction->setMessage(xp_get_string("file", "lookup"), 0);
1538
tmpAction->setMessage(xp_get_string("key", "lookup"), 1);
1539
tmpAction->setActionType(CAction::E_AT_LOOKUP);
1540
} else if(!strcmp(actionElem, "insert")) {
1541
tmpAction->setMessage(xp_get_string("file", "insert"), 0);
1542
tmpAction->setMessage(xp_get_string("value", "insert"), 1);
1543
tmpAction->setActionType(CAction::E_AT_INSERT);
1544
} else if(!strcmp(actionElem, "replace")) {
1545
tmpAction->setMessage(xp_get_string("file", "replace"), 0);
1546
tmpAction->setMessage(xp_get_string("line", "replace"), 1);
1547
tmpAction->setMessage(xp_get_string("value", "replace"), 2);
1548
tmpAction->setActionType(CAction::E_AT_REPLACE);
1549
} else if(!strcmp(actionElem, "setdest")) {
1550
tmpAction->setMessage(xp_get_string("host", actionElem), 0);
1551
tmpAction->setMessage(xp_get_string("port", actionElem), 1);
1552
tmpAction->setMessage(xp_get_string("protocol", actionElem), 2);
1553
tmpAction->setActionType(CAction::E_AT_SET_DEST);
1554
} else if(!strcmp(actionElem, "closecon")) {
1555
tmpAction->setActionType(CAction::E_AT_CLOSE_CON);
1556
} else if(!strcmp(actionElem, "strcmp")) {
1557
tmpAction->setVarId(xp_get_var("assign_to", "strcmp"));
1558
tmpAction->setVarInId(xp_get_var("variable", "strcmp"));
1559
if (xp_get_value("value")) {
1560
tmpAction->setStringValue(xp_get_string("value", "strcmp"));
1561
if (xp_get_value("variable2")) {
1562
ERROR("Can not have both a value and a variable2 for strcmp!");
1565
tmpAction->setVarIn2Id(xp_get_var("variable2", "strcmp"));
1567
tmpAction->setActionType(CAction::E_AT_VAR_STRCMP);
1568
} else if(!strcmp(actionElem, "trim")) {
1569
tmpAction->setVarId(xp_get_var("assign_to", "trim"));
1570
tmpAction->setActionType(CAction::E_AT_VAR_TRIM);
1571
} else if(!strcmp(actionElem, "exec")) {
1572
if((ptr = xp_get_value((char *)"command"))) {
1573
tmpAction->setActionType(CAction::E_AT_EXECUTE_CMD);
1574
tmpAction->setMessage(ptr);
1575
} /* end (ptr = xp_get_value("command") */ else if((ptr = xp_get_value((char *)"int_cmd"))) {
1576
CAction::T_IntCmdType type(CAction::E_INTCMD_STOPCALL); /* assume the default */
1578
if (!strcmp(ptr, "stop_now")) {
1579
type = CAction::E_INTCMD_STOP_NOW;
1580
} else if (!strcmp(ptr, "stop_gracefully")) {
1581
type = CAction::E_INTCMD_STOP_ALL;
1582
} else if (!strcmp(ptr, "stop_call")) {
1583
type = CAction::E_INTCMD_STOPCALL;
1586
/* the action is well formed, adding it in the */
1587
/* tmpActionTable */
1588
tmpAction->setActionType(CAction::E_AT_EXEC_INTCMD);
1589
tmpAction->setIntCmd(type);
1591
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
1592
tmpAction->setPcapArgs(ptr);
1593
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_AUDIO);
1595
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
1596
tmpAction->setPcapArgs(ptr);
1597
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_VIDEO);
1600
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
1601
ERROR("play_pcap_audio requires pcap support! Please recompile SIPp");
1602
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
1603
ERROR("play_pcap_video requires pcap support! Please recompile SIPp");
1606
ERROR("illegal <exec> in the scenario\n");
1609
ERROR("Unknown action: %s", actionElem);
1612
/* If the action was not well-formed, there should have already been an
1613
* ERROR declaration, thus it is safe to add it here at the end of the loop. */
1614
actions->setAction(tmpAction);
1621
// Action list for the message indexed by message_index in
1623
void scenario::getActionForThisMessage(message *message)
1627
if(!(actionElem = xp_open_element(0))) {
1630
if(strcmp(actionElem, "action")) {
1634
/* We actually have an action element. */
1635
if(message->M_actions != NULL) {
1636
ERROR("Duplicate action for %s index %d", message->desc, message->index);
1638
message->M_actions = new CActions();
1640
parseAction(message->M_actions);
1644
void scenario::getBookKeeping(message *message) {
1647
if((ptr = xp_get_value((char *)"rtd"))) {
1648
message -> stop_rtd = get_rtd(ptr, false);
1650
if ((ptr = xp_get_value((char *)"repeat_rtd"))) {
1651
if (message -> stop_rtd) {
1652
message-> repeat_rtd = get_bool(ptr, "repeat_rtd");
1654
ERROR("There is a repeat_rtd element without an rtd element");
1658
if((ptr = xp_get_value((char *)"start_rtd"))) {
1659
message -> start_rtd = get_rtd(ptr, true);
1662
if((ptr = xp_get_value((char *)"counter"))) {
1663
message -> counter = get_counter(ptr, "counter");
1667
void scenario::getCommonAttributes(message *message) {
1670
getBookKeeping(message);
1671
getActionForThisMessage(message);
1673
if((ptr = xp_get_value((char *)"lost"))) {
1674
message -> lost = get_double(ptr, "lost percentage");
1678
if((ptr = xp_get_value((char *)"crlf"))) {
1679
message -> crlf = 1;
1682
if (xp_get_value("hiderest")) {
1683
hidedefault = xp_get_bool("hiderest", "hiderest");
1685
message -> hide = xp_get_bool("hide", "hide", hidedefault);
1686
if((ptr = xp_get_value((char *)"display"))) {
1687
message -> display_str = strdup(ptr);
1690
message -> condexec = xp_get_var("condexec", "condexec variable", -1);
1691
message -> condexec_inverse = xp_get_bool("condexec_inverse", "condexec_inverse", false);
1693
if ((ptr = xp_get_value((char *)"next"))) {
1694
if (found_timewait) {
1695
ERROR("next labels are not allowed in <timewait> elements.");
1697
message -> nextLabel = strdup(ptr);
1698
message -> test = xp_get_var("test", "test variable", -1);
1699
if ( 0 != ( ptr = xp_get_value((char *)"chance") ) ) {
1700
float chance = get_double(ptr,"chance");
1701
/* probability of branch to next */
1702
if (( chance < 0.0 ) || (chance > 1.0 )) {
1703
ERROR("Chance %s not in range [0..1]", ptr);
1705
message -> chance = (int)((1.0-chance)*RAND_MAX);
1708
message -> chance = 0; /* always */
1712
if ((ptr = xp_get_value((char *)"ontimeout"))) {
1713
if (found_timewait) {
1714
ERROR("ontimeout labels are not allowed in <timewait> elements.");
1716
message -> onTimeoutLabel = strdup(ptr);
1720
// char* manipulation : create a int[] from a char*
1721
// test first is the char* is formed by int separeted by coma
1722
// and then create the table
1724
int isWellFormed(char * P_listeStr, int * nombre)
1726
char * ptr = P_listeStr;
1731
sizeOf = strlen(P_listeStr);
1732
// getting the number
1735
// is the string well formed ? [0-9] [,]
1737
for(int i=0; i<=sizeOf; i++)
1742
if(isANumber == false)
1768
if(isANumber == false)
1785
int createIntegerTable(char * P_listeStr,
1786
unsigned int ** listeInteger,
1790
char * ptr = P_listeStr;
1791
char * ptr_prev = P_listeStr;
1792
unsigned int current_int;
1795
if(isWellFormed(P_listeStr, sizeOfList) == 1)
1797
(*listeInteger) = new unsigned int[(*sizeOfList)];
1798
while((*ptr) != ('\0'))
1802
sscanf(ptr_prev, "%u", ¤t_int);
1803
if (nb<(*sizeOfList))
1804
(*listeInteger)[nb] = current_int;
1812
sscanf(ptr_prev, "%u", ¤t_int);
1813
if (nb<(*sizeOfList))
1814
(*listeInteger)[nb] = current_int;
1822
int createStringTable(char * inputString, char *** stringList, int *sizeOfList)
1833
char *p = strchr(inputString, ',');
1838
*stringList = (char **)realloc(*stringList, sizeof(char *) * (*sizeOfList + 1));
1839
(*stringList)[*sizeOfList] = strdup(inputString);
1844
while (inputString);
1849
void freeStringTable(char ** stringList, int sizeOfList) {
1850
for (int i = 0; i < sizeOfList; i++) {
1851
free(stringList[i]);
1856
/* These are the names of the scenarios, they must match the default_scenario table. */
1857
char *scenario_table[] = {
1871
int find_scenario(const char *scenario) {
1873
max = sizeof(scenario_table)/sizeof(scenario_table[0]);
1875
for (i = 0; i < max; i++) {
1876
if (!strcmp(scenario_table[i], scenario)) {
1881
ERROR("Invalid default scenario name '%s'.\n", scenario);
1885
// TIP: to integrate an existing XML scenario, use the following sed line:
1886
// cat ../3pcc-controller-B.xml | sed -e 's/\"/\\\"/g' -e 's/\(.*\)/\"\1\\n\"/'
1887
char * default_scenario [] = {
1888
/************* Default_scenario[0] ***************/
1890
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
1891
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
1893
"<!-- This program is free software; you can redistribute it and/or -->\n"
1894
"<!-- modify it under the terms of the GNU General Public License as -->\n"
1895
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
1896
"<!-- License, or (at your option) any later version. -->\n"
1898
"<!-- This program is distributed in the hope that it will be useful, -->\n"
1899
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
1900
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
1901
"<!-- GNU General Public License for more details. -->\n"
1903
"<!-- You should have received a copy of the GNU General Public License -->\n"
1904
"<!-- along with this program; if not, write to the -->\n"
1905
"<!-- Free Software Foundation, Inc., -->\n"
1906
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
1908
"<!-- Sipp default 'uac' scenario. -->\n"
1911
"<scenario name=\"Basic Sipstone UAC\">\n"
1912
" <!-- In client mode (sipp placing calls), the Call-ID MUST be -->\n"
1913
" <!-- generated by sipp. To do so, use [call_id] keyword. -->\n"
1914
" <send retrans=\"500\">\n"
1917
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1918
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1919
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1920
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
1921
" Call-ID: [call_id]\n"
1923
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1924
" Max-Forwards: 70\n"
1925
" Subject: Performance Test\n"
1926
" Content-Type: application/sdp\n"
1927
" Content-Length: [len]\n"
1930
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
1932
" c=IN IP[media_ip_type] [media_ip]\n"
1934
" m=audio [media_port] RTP/AVP 0\n"
1935
" a=rtpmap:0 PCMU/8000\n"
1940
" <recv response=\"100\"\n"
1941
" optional=\"true\">\n"
1944
" <recv response=\"180\" optional=\"true\">\n"
1947
" <recv response=\"183\" optional=\"true\">\n"
1950
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
1951
" <!-- are saved and used for following messages sent. Useful to test -->\n"
1952
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
1953
" <recv response=\"200\" rtd=\"true\">\n"
1956
" <!-- Packet lost can be simulated in any send/recv message by -->\n"
1957
" <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent. -->\n"
1961
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1962
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1963
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1964
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1965
" Call-ID: [call_id]\n"
1967
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1968
" Max-Forwards: 70\n"
1969
" Subject: Performance Test\n"
1970
" Content-Length: 0\n"
1975
" <!-- This delay can be customized by the -d command-line option -->\n"
1976
" <!-- or by adding a 'milliseconds = \"value\"' option here. -->\n"
1979
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
1980
" <send retrans=\"500\">\n"
1983
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1984
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1985
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1986
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1987
" Call-ID: [call_id]\n"
1989
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1990
" Max-Forwards: 70\n"
1991
" Subject: Performance Test\n"
1992
" Content-Length: 0\n"
1997
" <recv response=\"200\" crlf=\"true\">\n"
2000
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2001
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2003
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2004
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2010
/************* Default_scenario[1] ***************/
2012
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2013
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2015
"<!-- This program is free software; you can redistribute it and/or -->\n"
2016
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2017
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2018
"<!-- License, or (at your option) any later version. -->\n"
2020
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2021
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2022
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2023
"<!-- GNU General Public License for more details. -->\n"
2025
"<!-- You should have received a copy of the GNU General Public License -->\n"
2026
"<!-- along with this program; if not, write to the -->\n"
2027
"<!-- Free Software Foundation, Inc., -->\n"
2028
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2030
"<!-- Sipp default 'uas' scenario. -->\n"
2033
"<scenario name=\"Basic UAS responder\">\n"
2034
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
2035
" <!-- are saved and used for following messages sent. Useful to test -->\n"
2036
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
2037
" <recv request=\"INVITE\" crlf=\"true\">\n"
2040
" <!-- The '[last_*]' keyword is replaced automatically by the -->\n"
2041
" <!-- specified header if it was present in the last message received -->\n"
2042
" <!-- (except if it was a retransmission). If the header was not -->\n"
2043
" <!-- present or if no message has been received, the '[last_*]' -->\n"
2044
" <!-- keyword is discarded, and all bytes until the end of the line -->\n"
2045
" <!-- are also discarded. -->\n"
2047
" <!-- If the specified header was present several times in the -->\n"
2048
" <!-- message, all occurences are concatenated (CRLF seperated) -->\n"
2049
" <!-- to be used in place of the '[last_*]' keyword. -->\n"
2054
" SIP/2.0 180 Ringing\n"
2057
" [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2058
" [last_Call-ID:]\n"
2060
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2061
" Content-Length: 0\n"
2066
" <send retrans=\"500\">\n"
2072
" [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2073
" [last_Call-ID:]\n"
2075
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2076
" Content-Type: application/sdp\n"
2077
" Content-Length: [len]\n"
2080
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2082
" c=IN IP[media_ip_type] [media_ip]\n"
2084
" m=audio [media_port] RTP/AVP 0\n"
2085
" a=rtpmap:0 PCMU/8000\n"
2090
" <recv request=\"ACK\"\n"
2091
" optional=\"true\"\n"
2096
" <recv request=\"BYE\">\n"
2106
" [last_Call-ID:]\n"
2108
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2109
" Content-Length: 0\n"
2114
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2115
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2116
" <timewait milliseconds=\"4000\"/>\n"
2119
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2120
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2122
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2123
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2128
/************* Default_scenario[2] ***************/
2130
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2131
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2133
"<!-- This program is free software; you can redistribute it and/or -->\n"
2134
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2135
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2136
"<!-- License, or (at your option) any later version. -->\n"
2138
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2139
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2140
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2141
"<!-- GNU General Public License for more details. -->\n"
2143
"<!-- You should have received a copy of the GNU General Public License -->\n"
2144
"<!-- along with this program; if not, write to the -->\n"
2145
"<!-- Free Software Foundation, Inc., -->\n"
2146
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2148
"<!-- Sipp default 'regexp client' scenario. -->\n"
2151
"<scenario name=\"Client with regexp scenario\">\n"
2152
" <send retrans=\"500\">\n"
2155
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2156
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2157
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2158
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2159
" Call-ID: [call_id]\n"
2161
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2162
" Max-Forwards: 70\n"
2163
" Subject: Performance Test\n"
2164
" Content-Type: application/sdp\n"
2165
" Content-Length: [len]\n"
2168
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2170
" c=IN IP[media_ip_type] [media_ip]\n"
2172
" m=audio [media_port] RTP/AVP 0\n"
2173
" a=rtpmap:0 PCMU/8000\n"
2178
" <recv response=\"100\"\n"
2179
" optional=\"true\">\n"
2182
" <recv response=\"180\" optional=\"true\">\n"
2184
" <recv response=\"183\" optional=\"true\">\n"
2187
" <recv response=\"200\" start_rtd=\"true\">\n"
2188
" <!-- Definition of regexp in the action tag. The regexp must follow -->\n"
2189
" <!-- the Posix Extended standard (POSIX 1003.2), see: -->\n"
2191
" <!-- http://www.opengroup.org/onlinepubs/007908799/xbd/re.html -->\n"
2193
" <!-- regexp : Contain the regexp to use for matching the -->\n"
2194
" <!-- received message -->\n"
2195
" <!-- MANDATORY -->\n"
2196
" <!-- search_in : msg (try to match against the entire message) -->\n"
2197
" <!-- : hdr (try to match against a specific SIP header -->\n"
2198
" <!-- (passed in the header tag) -->\n"
2199
" <!-- OPTIONAL - default value : msg -->\n"
2200
" <!-- header : Header to try to match against. -->\n"
2201
" <!-- Only used when the search_in tag is set to hdr -->\n"
2202
" <!-- MANDATORY IF search_in is equal to hdr -->\n"
2203
" <!-- check_it : if set to true, the call is marked as failed if -->\n"
2204
" <!-- the regexp doesn't match. -->\n"
2205
" <!-- OPTIONAL - default value : false -->\n"
2206
" <!-- assign_to : contain the variable id (integer) or a list of -->\n"
2207
" <!-- variable id which will be used to store the -->\n"
2208
" <!-- result of the matching process between the regexp -->\n"
2209
" <!-- and the message. This variable can be re-used at -->\n"
2210
" <!-- a later time in the scenario using '[$n]' syntax -->\n"
2211
" <!-- where n is the variable id. -->\n"
2212
" <!-- MANDATORY -->\n"
2214
" <ereg regexp=\"[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[:][0-9]{1,5}\" \n"
2215
" search_in=\"msg\" \n"
2216
" check_it=\"true\" \n"
2217
" assign_to=\"1\"/>\n"
2218
" <ereg regexp=\".*\" \n"
2219
" search_in=\"hdr\" \n"
2220
" header=\"Contact:\" \n"
2221
" check_it=\"true\" \n"
2222
" assign_to=\"6\"/>\n"
2223
" <ereg regexp=\"o=([[:alnum:]]*) ([[:alnum:]]*) ([[:alnum:]]*)\"\n"
2224
" search_in=\"msg\" \n"
2225
" check_it=\"true\" \n"
2226
" assign_to=\"3,4,5,8\"/>\n"
2232
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2233
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2234
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2235
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2236
" Call-ID: [call_id]\n"
2238
" retrievedIp: [$1]\n"
2239
" retrievedContact:[$6]\n"
2240
" retrievedSdpOrigin:[$3]\n"
2241
" retrievedSdpOrigin-username:[$4]\n"
2242
" retrievedSdpOrigin-session-id:[$5]\n"
2243
" retrievedSdpOrigin-version:[$8]\n"
2244
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2245
" Max-Forwards: 70\n"
2246
" Subject: Performance Test\n"
2247
" Content-Length: 0\n"
2251
" <!-- This delay can be customized by the -d command-line option -->\n"
2252
" <!-- or by adding a 'milliseconds = \"value\"' option here. -->\n"
2253
" <pause milliseconds = \"1000\"/>\n"
2255
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2256
" <send retrans=\"500\">\n"
2259
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2260
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2261
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2262
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2263
" Call-ID: [call_id]\n"
2265
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2266
" Max-Forwards: 70\n"
2267
" Subject: Performance Test\n"
2268
" Content-Length: 0\n"
2273
" <recv response=\"200\" crlf=\"true\" rtd=\"true\">\n"
2276
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2277
" <ResponseTimeRepartition value=\"1000, 1040, 1080, 1120, 1160, 1200\"/>\n"
2279
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2280
" <CallLengthRepartition value=\"1000, 1100, 1200, 1300, 1400\"/>\n"
2285
/************* Default_scenario[3] ***************/
2287
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2288
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2290
"<!-- This program is free software; you can redistribute it and/or -->\n"
2291
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2292
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2293
"<!-- License, or (at your option) any later version. -->\n"
2295
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2296
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2297
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2298
"<!-- GNU General Public License for more details. -->\n"
2300
"<!-- You should have received a copy of the GNU General Public License -->\n"
2301
"<!-- along with this program; if not, write to the -->\n"
2302
"<!-- Free Software Foundation, Inc., -->\n"
2303
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2305
"<!-- 3PCC - Controller - A side -->\n"
2307
"<!-- A Controller B -->\n"
2308
"<!-- |(1) INVITE no SDP | | -->\n"
2309
"<!-- |<==================| | -->\n"
2310
"<!-- |(2) 200 offer1 | | -->\n"
2311
"<!-- |==================>| | -->\n"
2312
"<!-- | |(3) INVITE offer1 | -->\n"
2313
"<!-- | |==================>| -->\n"
2314
"<!-- | |(4) 200 OK answer1 | -->\n"
2315
"<!-- | |<==================| -->\n"
2316
"<!-- | |(5) ACK | -->\n"
2317
"<!-- | |==================>| -->\n"
2318
"<!-- |(6) ACK answer1 | | -->\n"
2319
"<!-- |<==================| | -->\n"
2320
"<!-- |(7) RTP | | -->\n"
2321
"<!-- |.......................................| -->\n"
2324
"<scenario name=\"3PCC Controller - A side\">\n"
2325
" <send retrans=\"500\">\n"
2328
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2329
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2330
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2331
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2332
" Call-ID: [call_id]\n"
2334
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2335
" Max-Forwards: 70\n"
2336
" Subject: Performance Test\n"
2337
" Content-Length: 0\n"
2342
" <recv response=\"100\" optional=\"true\"> </recv>\n"
2343
" <recv response=\"180\" optional=\"true\"> </recv>\n"
2344
" <recv response=\"183\" optional=\"true\"> </recv>\n"
2345
" <recv response=\"200\" crlf=\"true\" start_rtd=\"true\">\n"
2347
" <ereg regexp=\"Content-Type:.*\" \n"
2348
" search_in=\"msg\" \n"
2349
" assign_to=\"1\" /> \n"
2355
" Call-ID: [call_id]\n"
2363
" <ereg regexp=\"Content-Type:.*\" \n"
2364
" search_in=\"msg\" \n"
2365
" assign_to=\"2\" /> \n"
2370
" <send rtd=\"true\">\n"
2373
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2374
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2375
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2376
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2377
" Call-ID: [call_id]\n"
2379
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2380
" Max-Forwards: 70\n"
2381
" Subject: Performance Test\n"
2387
" <pause milliseconds=\"1000\"/>\n"
2389
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2390
" <send retrans=\"500\">\n"
2393
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2394
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2395
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2396
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2397
" Call-ID: [call_id]\n"
2399
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2400
" Max-Forwards: 70\n"
2401
" Subject: Performance Test\n"
2402
" Content-Length: 0\n"
2407
" <recv response=\"200\" crlf=\"true\"> </recv>\n"
2412
/************* Default_scenario[4] ***************/
2414
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2415
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2417
"<!-- This program is free software; you can redistribute it and/or -->\n"
2418
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2419
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2420
"<!-- License, or (at your option) any later version. -->\n"
2422
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2423
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2424
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2425
"<!-- GNU General Public License for more details. -->\n"
2427
"<!-- You should have received a copy of the GNU General Public License -->\n"
2428
"<!-- along with this program; if not, write to the -->\n"
2429
"<!-- Free Software Foundation, Inc., -->\n"
2430
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2432
"<!-- 3PCC - Controller - B side -->\n"
2434
"<!-- A Controller B -->\n"
2435
"<!-- |(1) INVITE no SDP | | -->\n"
2436
"<!-- |<==================| | -->\n"
2437
"<!-- |(2) 200 offer1 | | -->\n"
2438
"<!-- |==================>| | -->\n"
2439
"<!-- | |(3) INVITE offer1 | -->\n"
2440
"<!-- | |==================>| -->\n"
2441
"<!-- | |(4) 200 OK answer1 | -->\n"
2442
"<!-- | |<==================| -->\n"
2443
"<!-- | |(5) ACK | -->\n"
2444
"<!-- | |==================>| -->\n"
2445
"<!-- |(6) ACK answer1 | | -->\n"
2446
"<!-- |<==================| | -->\n"
2447
"<!-- |(7) RTP | | -->\n"
2448
"<!-- |.......................................| -->\n"
2452
"<scenario name=\"3PCC Controller - B side\">\n"
2456
" <ereg regexp=\"Content-Type:.*\" \n"
2457
" search_in=\"msg\" \n"
2458
" assign_to=\"1\" /> \n"
2462
" <send retrans=\"500\">\n"
2465
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2466
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2467
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2468
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2469
" Call-ID: [call_id]\n"
2471
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2472
" Max-Forwards: 70\n"
2473
" Subject: Performance Test\n"
2479
" <recv response=\"100\" optional=\"true\"> </recv>\n"
2480
" <recv response=\"180\" optional=\"true\"> </recv>\n"
2481
" <recv response=\"183\" optional=\"true\"> </recv>\n"
2482
" <recv response=\"200\" crlf=\"true\">\n"
2484
" <ereg regexp=\"Content-Type:.*\" \n"
2485
" search_in=\"msg\" \n"
2486
" assign_to=\"2\" /> \n"
2491
" <send start_rtd=\"true\">\n"
2494
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2495
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2496
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2497
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2498
" Call-ID: [call_id]\n"
2500
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2501
" Max-Forwards: 70\n"
2502
" Subject: Performance Test\n"
2503
" Content-Length: 0\n"
2510
" Call-ID: [call_id]\n"
2516
" <pause milliseconds=\"1000\"/>\n"
2519
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2520
" <send retrans=\"500\" rtd=\"true\">\n"
2523
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2524
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2525
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2526
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2527
" Call-ID: [call_id]\n"
2529
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2530
" Max-Forwards: 70\n"
2531
" Subject: Performance Test\n"
2532
" Content-Length: 0\n"
2537
" <recv response=\"200\" crlf=\"true\">\n"
2544
/************* Default_scenario[5] ***************/
2546
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2547
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2549
"<!-- This program is free software; you can redistribute it and/or -->\n"
2550
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2551
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2552
"<!-- License, or (at your option) any later version. -->\n"
2554
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2555
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2556
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2557
"<!-- GNU General Public License for more details. -->\n"
2559
"<!-- You should have received a copy of the GNU General Public License -->\n"
2560
"<!-- along with this program; if not, write to the -->\n"
2561
"<!-- Free Software Foundation, Inc., -->\n"
2562
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2564
"<!-- 3PCC - A side emulator -->\n"
2566
"<!-- A Controller B -->\n"
2567
"<!-- |(1) INVITE no SDP | | -->\n"
2568
"<!-- |<==================| | -->\n"
2569
"<!-- |(2) 200 offer1 | | -->\n"
2570
"<!-- |==================>| | -->\n"
2571
"<!-- | |(3) INVITE offer1 | -->\n"
2572
"<!-- | |==================>| -->\n"
2573
"<!-- | |(4) 200 OK answer1 | -->\n"
2574
"<!-- | |<==================| -->\n"
2575
"<!-- | |(5) ACK | -->\n"
2576
"<!-- | |==================>| -->\n"
2577
"<!-- |(6) ACK answer1 | | -->\n"
2578
"<!-- |<==================| | -->\n"
2579
"<!-- |(7) RTP | | -->\n"
2580
"<!-- |.......................................| -->\n"
2584
"<scenario name=\"3PCC A side\">\n"
2585
" <recv request=\"INVITE\" crlf=\"true\">\n"
2594
" [last_To:];tag=[pid]SIPpTag05[call_number]\n"
2595
" [last_Call-ID:]\n"
2597
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2598
" Content-Type: application/sdp\n"
2599
" Content-Length: [len]\n"
2602
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2604
" c=IN IP[media_ip_type] [media_ip]\n"
2606
" m=audio [media_port] RTP/AVP 0\n"
2607
" a=rtpmap:0 PCMU/8000\n"
2612
" <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2614
" <!-- RTP flow starts from here! -->\n"
2616
" <recv request=\"BYE\" crlf=\"true\"> </recv>\n"
2625
" [last_Call-ID:]\n"
2627
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2628
" Content-Length: 0\n"
2633
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2634
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2635
" <timewait milliseconds=\"2000\"/>\n"
2640
/************* Default_scenario[6] ***************/
2642
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2643
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2645
"<!-- This program is free software; you can redistribute it and/or -->\n"
2646
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2647
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2648
"<!-- License, or (at your option) any later version. -->\n"
2650
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2651
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2652
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2653
"<!-- GNU General Public License for more details. -->\n"
2655
"<!-- You should have received a copy of the GNU General Public License -->\n"
2656
"<!-- along with this program; if not, write to the -->\n"
2657
"<!-- Free Software Foundation, Inc., -->\n"
2658
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2660
"<!-- 3PCC - B side emulator -->\n"
2662
"<!-- A Controller B -->\n"
2663
"<!-- |(1) INVITE no SDP | | -->\n"
2664
"<!-- |<==================| | -->\n"
2665
"<!-- |(2) 200 offer1 | | -->\n"
2666
"<!-- |==================>| | -->\n"
2667
"<!-- | |(3) INVITE offer1 | -->\n"
2668
"<!-- | |==================>| -->\n"
2669
"<!-- | |(4) 200 OK answer1 | -->\n"
2670
"<!-- | |<==================| -->\n"
2671
"<!-- | |(5) ACK | -->\n"
2672
"<!-- | |==================>| -->\n"
2673
"<!-- |(6) ACK answer1 | | -->\n"
2674
"<!-- |<==================| | -->\n"
2675
"<!-- |(7) RTP | | -->\n"
2676
"<!-- |.......................................| -->\n"
2681
"<scenario name=\"3PCC B side\">\n"
2682
" <recv request=\"INVITE\" crlf=\"true\"> </recv>\n"
2690
" [last_To:];tag=[pid]SIPpTag06[call_number]\n"
2691
" [last_Call-ID:]\n"
2693
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2694
" Content-Type: application/sdp\n"
2695
" Content-Length: [len]\n"
2698
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2700
" c=IN IP[media_ip_type] [media_ip]\n"
2702
" m=audio [media_port] RTP/AVP 0\n"
2703
" a=rtpmap:0 PCMU/8000\n"
2708
" <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2710
" <!-- RTP flow starts from here! -->\n"
2712
" <recv request=\"BYE\"> </recv>\n"
2721
" [last_Call-ID:]\n"
2723
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2724
" Content-Length: 0\n"
2729
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2730
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2731
" <timewait milliseconds=\"2000\"/>\n"
2735
/************* Default_scenario[7] ***************/
2737
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2738
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2740
"<!-- This program is free software; you can redistribute it and/or -->\n"
2741
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2742
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2743
"<!-- License, or (at your option) any later version. -->\n"
2745
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2746
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2747
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2748
"<!-- GNU General Public License for more details. -->\n"
2750
"<!-- You should have received a copy of the GNU General Public License -->\n"
2751
"<!-- along with this program; if not, write to the -->\n"
2752
"<!-- Free Software Foundation, Inc., -->\n"
2753
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2755
"<!-- Sipp default 'branchc' scenario. -->\n"
2758
"<scenario name=\"branch_client\">\n"
2759
" <send retrans=\"500\">\n"
2762
" REGISTER sip:CA.cym.com SIP/2.0\n"
2763
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2764
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07[call_number]\n"
2765
" To: ua1 <sip:ua1@nnl.cym:[local_port]>\n"
2766
" Call-ID: [call_id]\n"
2767
" CSeq: 1 REGISTER\n"
2768
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2769
" Content-Length: 0\n"
2775
" <!-- simple case - just jump over a line -->\n"
2776
" <recv response=\"200\" rtd=\"true\" next=\"5\">\n"
2779
" <recv response=\"200\">\n"
2782
" <label id=\"5\"/>\n"
2784
" <send retrans=\"500\">\n"
2787
" INVITE sip:ua2@CA.cym.com SIP/2.0\n"
2788
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2789
" From: ua[call_number] <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2790
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>\n"
2791
" Call-ID: [call_id]\n"
2793
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2794
" Max-Forwards: 70\n"
2795
" Subject: Performance Test\n"
2796
" Content-Type: application/sdp\n"
2797
" Content-Length: [len]\n"
2800
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2802
" c=IN IP[media_ip_type] [media_ip]\n"
2804
" m=audio [media_port] RTP/AVP 0\n"
2805
" a=rtpmap:0 PCMU/8000\n"
2810
" <recv response=\"100\" optional=\"true\">\n"
2813
" <recv response=\"180\" optional=\"true\">\n"
2816
" <recv response=\"183\" optional=\"true\">\n"
2819
" <!-- Do something different on an optional receive -->\n"
2820
" <recv response=\"403\" optional=\"true\" next=\"1\">\n"
2823
" <recv response=\"200\">\n"
2825
" <ereg regexp=\"ua25\"\n"
2826
" search_in=\"hdr\"\n"
2827
" header=\"From: \"\n"
2828
" assign_to=\"8\"/>\n"
2832
" <!-- set variable 8 above on 25th call, send the ACK but skip the pause for it -->\n"
2833
" <send next=\"1\" test=\"8\">\n"
2836
" ACK sip:ua2@CA.cym.com SIP/2.0\n"
2837
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2838
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2839
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2840
" Call-ID: [call_id]\n"
2842
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2843
" Max-Forwards: 70\n"
2844
" Subject: Performance Test\n"
2845
" Content-Length: 0\n"
2850
" <pause milliseconds=\"5000\"/>\n"
2852
" <label id=\"1\"/>\n"
2854
" <send retrans=\"500\">\n"
2857
" BYE sip:ua2@CA.cym.com SIP/2.0\n"
2858
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2859
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2860
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2861
" Call-ID: [call_id]\n"
2863
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2864
" Max-Forwards: 70\n"
2865
" Subject: Performance Test\n"
2866
" Content-Length: 0\n"
2871
" <recv response=\"200\" crlf=\"true\">\n"
2874
" <pause milliseconds=\"4000\"/>\n"
2876
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2877
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2879
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2880
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2885
/************* Default_scenario[8] ***************/
2887
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2888
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2890
"<!-- This program is free software; you can redistribute it and/or -->\n"
2891
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2892
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2893
"<!-- License, or (at your option) any later version. -->\n"
2895
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2896
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2897
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2898
"<!-- GNU General Public License for more details. -->\n"
2900
"<!-- You should have received a copy of the GNU General Public License -->\n"
2901
"<!-- along with this program; if not, write to the -->\n"
2902
"<!-- Free Software Foundation, Inc., -->\n"
2903
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2905
"<!-- Sipp default 'branchs' scenario. -->\n"
2908
"<scenario name=\"branch_server\">\n"
2909
" <recv request=\"REGISTER\">\n"
2918
" [last_To:];tag=[pid]SIPpTag08[call_number]\n"
2919
" [last_Call-ID:]\n"
2921
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2922
" Content-Length: 0\n"
2928
" <!-- Set variable 3 if the ua is of the form ua2... -->\n"
2929
" <recv request=\"INVITE\" crlf=\"true\">\n"
2931
" <ereg regexp=\"ua2\"\n"
2932
" search_in=\"hdr\"\n"
2933
" header=\"From: \"\n"
2934
" assign_to=\"3\"/>\n"
2938
" <!-- send 180 then trying if variable 3 is set -->\n"
2939
" <send next=\"1\" test=\"3\">\n"
2942
" SIP/2.0 180 Ringing\n"
2945
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2946
" [last_Call-ID:]\n"
2948
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2949
" Content-Length: 0\n"
2954
" <!-- if not, send a 403 error then skip to wait for a BYE -->\n"
2955
" <send next=\"2\">\n"
2958
" SIP/2.0 403 Error\n"
2961
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2962
" [last_Call-ID:]\n"
2964
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2965
" Content-Length: 0\n"
2970
" <label id=\"1\"/>\n"
2975
" SIP/2.0 100 Trying\n"
2978
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2979
" [last_Call-ID:]\n"
2981
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2982
" Content-Length: 0\n"
2987
" <send retrans=\"500\">\n"
2993
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2994
" [last_Call-ID:]\n"
2996
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2997
" Content-Type: application/sdp\n"
2998
" Content-Length: [len]\n"
3001
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
3003
" c=IN IP[media_ip_type] [media_ip]\n"
3005
" m=audio [media_port] RTP/AVP 0\n"
3006
" a=rtpmap:0 PCMU/8000\n"
3011
" <recv request=\"ACK\"\n"
3012
" optional=\"true\"\n"
3017
" <label id=\"2\"/>\n"
3019
" <recv request=\"BYE\">\n"
3029
" [last_Call-ID:]\n"
3031
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3032
" Content-Length: 0\n"
3037
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
3038
" <!-- able to retransmit it if we receive the BYE again. -->\n"
3039
" <timewait milliseconds=\"4000\"/>\n"
3041
" <!-- Definition of the response time repartition table (unit is ms) -->\n"
3042
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3044
" <!-- Definition of the call length repartition table (unit is ms) -->\n"
3045
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3050
/* Although this scenario will not work without pcap play enabled, there is no
3051
* harm in including it in the binary anyway, because the user could have
3052
* dumped it and passed it with -sf. */
3054
/************* Default_scenario[9] ***************/
3056
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3057
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3059
"<!-- This program is free software; you can redistribute it and/or -->\n"
3060
"<!-- modify it under the terms of the GNU General Public License as -->\n"
3061
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3062
"<!-- License, or (at your option) any later version. -->\n"
3064
"<!-- This program is distributed in the hope that it will be useful, -->\n"
3065
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
3066
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
3067
"<!-- GNU General Public License for more details. -->\n"
3069
"<!-- You should have received a copy of the GNU General Public License -->\n"
3070
"<!-- along with this program; if not, write to the -->\n"
3071
"<!-- Free Software Foundation, Inc., -->\n"
3072
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
3074
"<!-- Sipp 'uac' scenario with pcap (rtp) play -->\n"
3077
"<scenario name=\"UAC with media\">\n"
3078
" <!-- In client mode (sipp placing calls), the Call-ID MUST be -->\n"
3079
" <!-- generated by sipp. To do so, use [call_id] keyword. -->\n"
3080
" <send retrans=\"500\">\n"
3083
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3084
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3085
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3086
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
3087
" Call-ID: [call_id]\n"
3089
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3090
" Max-Forwards: 70\n"
3091
" Subject: Performance Test\n"
3092
" Content-Type: application/sdp\n"
3093
" Content-Length: [len]\n"
3096
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
3098
" c=IN IP[local_ip_type] [local_ip]\n"
3100
" m=audio [auto_media_port] RTP/AVP 8 101\n"
3101
" a=rtpmap:8 PCMA/8000\n"
3102
" a=rtpmap:101 telephone-event/8000\n"
3103
" a=fmtp:101 0-11,16\n"
3108
" <recv response=\"100\" optional=\"true\">\n"
3111
" <recv response=\"180\" optional=\"true\">\n"
3114
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
3115
" <!-- are saved and used for following messages sent. Useful to test -->\n"
3116
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
3117
" <recv response=\"200\" rtd=\"true\" crlf=\"true\">\n"
3120
" <!-- Packet lost can be simulated in any send/recv message by -->\n"
3121
" <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent. -->\n"
3125
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3126
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3127
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3128
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3129
" Call-ID: [call_id]\n"
3131
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3132
" Max-Forwards: 70\n"
3133
" Subject: Performance Test\n"
3134
" Content-Length: 0\n"
3139
" <!-- Play a pre-recorded PCAP file (RTP stream) -->\n"
3142
" <exec play_pcap_audio=\"pcap/g711a.pcap\"/>\n"
3146
" <!-- Pause 8 seconds, which is approximately the duration of the -->\n"
3147
" <!-- PCAP file -->\n"
3148
" <pause milliseconds=\"8000\"/>\n"
3150
" <!-- Play an out of band DTMF '1' -->\n"
3153
" <exec play_pcap_audio=\"pcap/dtmf_2833_1.pcap\"/>\n"
3157
" <pause milliseconds=\"1000\"/>\n"
3159
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
3160
" <send retrans=\"500\">\n"
3163
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3164
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3165
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3166
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3167
" Call-ID: [call_id]\n"
3169
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3170
" Max-Forwards: 70\n"
3171
" Subject: Performance Test\n"
3172
" Content-Length: 0\n"
3177
" <recv response=\"200\" crlf=\"true\">\n"
3180
" <!-- definition of the response time repartition table (unit is ms) -->\n"
3181
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3183
" <!-- definition of the call length repartition table (unit is ms) -->\n"
3184
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3188
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3189
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3191
"<!-- This program is free software; you can redistribute it and/or -->\n"
3192
"<!-- modify it under the terms of the GNU General Public License as -->\n"
3193
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3194
"<!-- License, or (at your option) any later version. -->\n"
3196
"<!-- This program is distributed in the hope that it will be useful, -->\n"
3197
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
3198
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
3199
"<!-- GNU General Public License for more details. -->\n"
3201
"<!-- You should have received a copy of the GNU General Public License -->\n"
3202
"<!-- along with this program; if not, write to the -->\n"
3203
"<!-- Free Software Foundation, Inc., -->\n"
3204
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
3206
"<!-- Sipp default 'uas' scenario. -->\n"
3209
"<scenario name=\"Out-of-call UAS\">\n"
3210
" <recv request=\".*\" regexp_match=\"true\" />\n"
3218
" [last_Call-ID:]\n"
3220
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3221
" Content-Length: 0\n"
3226
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
3227
" <!-- able to retransmit it if we receive the BYE again. -->\n"
3228
" <timewait milliseconds=\"4000\"/>\n"
3231
" <!-- definition of the response time repartition table (unit is ms) -->\n"
3232
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3234
" <!-- definition of the call length repartition table (unit is ms) -->\n"
3235
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"