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>
37
/************************ Class Constructor *************************/
39
message::message(int index, const char *desc)
43
pause_distribution = NULL;
47
bShouldRecordRoutes = 0;
49
bShouldAuthenticate = 0;
61
regexp_compile = NULL;
73
condexec_inverse = false;
74
chance = 0;/* meaning always */
78
onTimeoutLabel = NULL;
81
/* 3pcc extended mode */
103
content_length_flag = ContentLengthNoPresent;
105
/* How to match responses to this message. */
109
recv_response_for_cseq_method_list = NULL;
114
if(M_actions != NULL)
117
if(send_scheme != NULL)
120
if(recv_request != NULL)
123
if(regexp_compile != NULL)
124
regfree(regexp_compile);
125
free(regexp_compile);
128
if (pause_distribution) {
129
delete pause_distribution;
132
if(M_sendCmdData != NULL)
133
delete M_sendCmdData;
139
free(recv_response_for_cseq_method_list);
142
/******** Global variables which compose the scenario file **********/
144
scenario *main_scenario;
145
scenario *ooc_scenario;
146
scenario *display_scenario;
148
/* This mode setting refers to whether we open calls autonomously (MODE_CLIENT)
149
* or in response to requests (MODE_SERVER). */
150
int creationMode = MODE_CLIENT;
151
/* Send mode. Do we send to a fixed address or to the last one we got. */
152
int sendMode = MODE_CLIENT;
153
/* This describes what our 3PCC behavior is. */
154
int thirdPartyMode = MODE_3PCC_NONE;
156
/*************** Helper functions for various types *****************/
157
long get_long(const char *ptr, const char *what) {
161
ret = strtol(ptr, &endptr, 0);
163
ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
168
unsigned long long get_long_long(const char *ptr, const char *what) {
170
unsigned long long ret;
172
ret = strtoull(ptr, &endptr, 0);
174
ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
179
/* This function returns a time in milliseconds from a string.
180
* The multiplier is used to convert from the default input type into
181
* milliseconds. For example, for seconds you should use 1000 and for
182
* milliseconds use 1. */
183
long get_time(const char *ptr, const char *what, int multiplier) {
190
if (!isdigit(*ptr)) {
191
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
194
for (i = 0, p = ptr; *p; p++) {
200
if (i == 1) { /* mm:ss */
201
ERROR("%s, \"%s\" mm:ss not implemented yet!\n", what, ptr);
203
else if (i == 2) { /* hh:mm:ss */
204
ERROR("%s, \"%s\" hh:mm:ss not implemented yet!\n", what, ptr);
206
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
209
dret = strtod(ptr, &endptr);
211
if (!strcmp(endptr, "s")) { /* Seconds */
212
ret = (long)(dret * 1000);
213
} else if (!strcmp(endptr, "ms")) { /* Milliseconds. */
215
} else if (!strcmp(endptr, "m")) { /* Minutes. */
216
ret = (long)(dret * 60000);
217
} else if (!strcmp(endptr, "h")) { /* Hours. */
218
ret = (long)(dret * 60 * 60 * 1000);
220
ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
223
ret = (long)(dret * multiplier);
228
double get_double(const char *ptr, const char *what) {
232
ret = strtod(ptr, &endptr);
234
ERROR("%s, \"%s\" is not a floating point number!\n", what, ptr);
239
char * xp_get_string(const char *name, const char *what) {
242
if (!(ptr = xp_get_value(name))) {
243
ERROR("%s is missing the required '%s' parameter.", what, name);
249
double xp_get_double(const char *name, const char *what) {
254
if (!(ptr = xp_get_value(name))) {
255
ERROR("%s is missing the required '%s' parameter.", what, name);
257
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
258
sprintf(helptext, "%s '%s' parameter", what, name);
259
val = get_double(ptr, helptext);
265
double xp_get_double(const char *name, const char *what, double defval) {
266
if (!(xp_get_value(name))) {
269
return xp_get_double(name, what);
272
long xp_get_long(const char *name, const char *what) {
277
if (!(ptr = xp_get_value(name))) {
278
ERROR("%s is missing the required '%s' parameter.", what, name);
280
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
281
sprintf(helptext, "%s '%s' parameter", what, name);
282
val = get_long(ptr, helptext);
288
long xp_get_long(const char *name, const char *what, long defval) {
289
if (!(xp_get_value(name))) {
292
return xp_get_long(name, what);
296
double xp_get_bool(const char *name, const char *what) {
301
if (!(ptr = xp_get_value(name))) {
302
ERROR("%s is missing the required '%s' parameter.", what, name);
304
helptext = (char *)malloc(100 + strlen(name) + strlen(what));
305
sprintf(helptext, "%s '%s' parameter", what, name);
306
val = get_bool(ptr, helptext);
312
double xp_get_bool(const char *name, const char *what, bool defval) {
313
if (!(xp_get_value(name))) {
316
return xp_get_bool(name, what);
319
int scenario::get_txn(const char *txnName, const char *what, bool start, bool isInvite, bool isAck) {
320
/* Check the name's validity. */
321
if (txnName[0] == '\0') {
322
ERROR("Variable names may not be empty for %s\n", what);
324
if (strcspn(txnName, "$,") != strlen(txnName)) {
325
ERROR("Variable names may not contain $ or , for %s\n", what);
328
/* If this transaction has already been used, then we have nothing to do. */
329
str_int_map::iterator txn_it = txnMap.find(txnName);
330
if (txn_it != txnMap.end()) {
332
/* We need to fill in the invite field. */
333
transactions[txn_it->second - 1].started++;
335
transactions[txn_it->second - 1].acks++;
337
transactions[txn_it->second - 1].responses++;
339
return txn_it->second;
342
/* Assign this variable the next slot. */
343
struct txnControlInfo transaction;
345
transaction.name = strdup(txnName);
347
transaction.started = 1;
348
transaction.responses = 0;
349
transaction.acks = 0;
350
transaction.isInvite = isInvite;
352
/* Does not start or respond to this txn. */
353
transaction.started = 0;
354
transaction.responses = 0;
355
transaction.acks = 1;
356
transaction.isInvite = false;
358
transaction.started = 0;
359
transaction.responses = 1;
360
transaction.acks = 0;
361
transaction.isInvite = false;
364
transactions.push_back(transaction);
365
int txnNum = transactions.size();
366
txnMap[txnName] = txnNum;
371
int scenario::find_var(const char *varName, const char *what) {
372
return allocVars->find(varName, false);
375
int scenario::get_var(const char *varName, const char *what) {
376
/* Check the name's validity. */
377
if (varName[0] == '\0') {
378
ERROR("Transaction names may not be empty for %s\n", what);
380
if (strcspn(varName, "$,") != strlen(varName)) {
381
ERROR("Transaction names may not contain $ or , for %s\n", what);
384
return allocVars->find(varName, true);
387
int scenario::xp_get_var(const char *name, const char *what) {
390
if (!(ptr = xp_get_value(name))) {
391
ERROR("%s is missing the required '%s' variable parameter.", what, name);
394
return get_var(ptr, what);
397
int xp_get_optional(const char *name, const char *what) {
398
char *ptr = xp_get_value(name);
400
if (!(ptr = xp_get_value(name))) {
401
return OPTIONAL_FALSE;
404
if(!strcmp(ptr, "true")) {
405
return OPTIONAL_TRUE;
406
} else if(!strcmp(ptr, "global")) {
407
return OPTIONAL_GLOBAL;
408
} else if(!strcmp(ptr, "false")) {
409
return OPTIONAL_FALSE;
411
ERROR("Could not understand optional value for %s: %s", what, ptr);
414
return OPTIONAL_FALSE;
418
int scenario::xp_get_var(const char *name, const char *what, int defval) {
421
if (!(ptr = xp_get_value(name))) {
425
return xp_get_var(name, what);
428
bool get_bool(const char *ptr, const char *what) {
432
if (!strcmp(ptr, "true")) {
435
if (!strcmp(ptr, "false")) {
439
ret = strtol(ptr, &endptr, 0);
441
ERROR("%s, \"%s\" is not a valid boolean!\n", what, ptr);
443
return ret ? true : false;
446
/* Pretty print a time. */
447
char *time_string(int ms) {
451
snprintf(tmp, sizeof(tmp), "%dms", ms);
452
} else if (ms < 100000) {
453
snprintf(tmp, sizeof(tmp), "%.1fs", ((float)ms)/1000);
455
snprintf(tmp, sizeof(tmp), "%ds", ms/1000);
461
int time_string(double ms, char *res, int reslen) {
463
/* Less then 10 seconds we represent accurately. */
464
if ((int)(ms + 0.9999) == (int)(ms)) {
465
/* We have an integer, or close enough to it. */
466
return snprintf(res, reslen, "%dms", (int)ms);
469
return snprintf(res, reslen, "%.2lfms", ms);
471
return snprintf(res, reslen, "%.1lfms", ms);
474
} else if (ms < 60000) {
475
/* We round to 100ms for times less than a minute. */
476
return snprintf(res, reslen, "%.1fs", ms/1000);
477
} else if (ms < 60 * 60000) {
478
/* We round to 1s for times more than a minute. */
479
int s = (unsigned int)(ms / 1000);
482
return snprintf(res, reslen, "%d:%02d", m, s);
484
int s = (unsigned int)(ms / 1000);
489
return snprintf(res, reslen, "%d:%02d:%02d", h, m, s);
493
char *double_time_string(double ms) {
497
snprintf(tmp, sizeof(tmp), "%.2lfms", ms);
498
} else if (ms < 10000) {
499
snprintf(tmp, sizeof(tmp), "%.1lfms", ms);
500
} else if (ms < 100000) {
501
snprintf(tmp, sizeof(tmp), "%.1lfs", ms / 1000);
503
snprintf(tmp, sizeof(tmp), "%ds", (int)(ms/1000));
509
/* For backwards compatibility, we assign "true" to slot 1, false to 0, and
510
* allow other valid integers. */
511
int scenario::get_rtd(const char *ptr, bool start) {
512
if(!strcmp(ptr, (char *)"false"))
515
if(!strcmp(ptr, (char *)"true"))
516
return stats->findRtd("1", start);
518
return stats->findRtd(ptr, start);
522
int scenario::get_counter(const char *ptr, const char *what) {
523
/* Check the name's validity. */
524
if (ptr[0] == '\0') {
525
ERROR("Counter names names may not be empty for %s\n", what);
527
if (strcspn(ptr, "$,") != strlen(ptr)) {
528
ERROR("Counter names may not contain $ or , for %s\n", what);
531
return stats->findCounter(ptr, true);
535
/* Some validation functions. */
537
void scenario::validate_variable_usage() {
538
allocVars->validate();
541
void scenario::validate_txn_usage() {
542
for (unsigned int i = 0; i < transactions.size(); i++) {
543
if(transactions[i].started == 0) {
544
ERROR("Transaction %s is never started!\n", transactions[i].name);
545
} else if(transactions[i].responses == 0) {
546
ERROR("Transaction %s has no responses defined!\n", transactions[i].name);
548
if (transactions[i].isInvite && transactions[i].acks == 0) {
549
ERROR("Transaction %s is an INVITE transaction without an ACK!\n", transactions[i].name);
551
if (!transactions[i].isInvite && (transactions[i].acks > 0)) {
552
ERROR("Transaction %s is a non-INVITE transaction with an ACK!\n", transactions[i].name);
557
/* Apply the next and ontimeout labels according to our map. */
558
void scenario::apply_labels(msgvec v, str_int_map labels) {
559
for (unsigned int i = 0; i < v.size(); i++) {
560
if (v[i]->nextLabel) {
561
str_int_map::iterator label_it = labels.find(v[i]->nextLabel);
562
if (label_it == labels.end()) {
563
ERROR("The label '%s' was not defined (index %d, next attribute)\n", v[i]->nextLabel, i);
565
v[i]->next = label_it->second;
567
if (v[i]->onTimeoutLabel) {
568
str_int_map::iterator label_it = labels.find(v[i]->onTimeoutLabel);
569
if (label_it == labels.end()) {
570
ERROR("The label '%s' was not defined (index %d, ontimeout attribute)\n", v[i]->onTimeoutLabel, i);
572
v[i]->on_timeout = label_it->second;
577
int get_cr_number(char *src)
582
if(*ptr == '\n') res++;
588
char *clean_cdata(char *ptr, int *removed_crlf = NULL) {
591
while((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\n')) ptr++;
593
msg = (char *) malloc(strlen(ptr) + 3);
594
if(!msg) { ERROR("Memory Overflow"); }
597
ptr = msg + strlen(msg);
600
while((ptr >= msg) &&
604
if(*ptr == '\n' && removed_crlf) {
610
if(!strstr(msg, "\n\n")) {
615
ERROR("Empty cdata in xml scenario file");
617
while ((ptr = strstr(msg, "\n "))) {
618
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
620
while ((ptr = strstr(msg, " \n"))) {
621
memmove(ptr, ptr + 1, strlen(ptr));
623
while ((ptr = strstr(msg, "\n\t"))) {
624
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
626
while ((ptr = strstr(msg, "\t\n"))) {
627
memmove(ptr, ptr + 1, strlen(ptr));
635
/********************** Scenario File analyser **********************/
637
void scenario::checkOptionalRecv(char *elem, unsigned int scenario_file_cursor) {
638
if (last_recv_optional) {
639
ERROR("<recv> before <%s> sequence without a mandatory message. Please remove one 'optional=true' (element %d).", elem, scenario_file_cursor);
641
last_recv_optional = false;
644
scenario::scenario(char * filename, int deflt)
647
char *method_list = NULL;
648
unsigned int scenario_file_cursor = 0;
649
int L_content_length = 0 ;
652
last_recv_optional = false;
655
if(!xp_set_xml_buffer_from_file(filename)) {
656
ERROR("Unable to load or parse '%s' xml scenario file", filename);
659
if(!xp_set_xml_buffer_from_string(default_scenario[deflt])) {
660
ERROR("Unable to load default xml scenario file");
665
allocVars = new AllocVariableTable(userVariables);
669
elem = xp_open_element(0);
671
ERROR("No element in xml scenario file");
673
if(strcmp("scenario", elem)) {
674
ERROR("No 'scenario' section in xml scenario file");
677
if(char *ptr = xp_get_value((char *)"name")) {
684
found_timewait = false;
686
scenario_file_cursor = 0;
688
while ((elem = xp_open_element(scenario_file_cursor))) {
690
scenario_file_cursor ++;
692
if(!strcmp(elem, "CallLengthRepartition")) {
693
ptr = xp_get_string("value", "CallLengthRepartition");
694
stats->setRepartitionCallLength(ptr);
696
} else if(!strcmp(elem, "ResponseTimeRepartition")) {
697
ptr = xp_get_string("value", "ResponseTimeRepartition");
698
stats->setRepartitionResponseTime(ptr);
700
} else if(!strcmp(elem, "Global")) {
701
ptr = xp_get_string("variables", "Global");
703
char ** currentTabVarName = NULL;
704
int currentNbVarNames;
706
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
707
for (int i = 0; i < currentNbVarNames; i++) {
708
globalVariables->find(currentTabVarName[i], true);
710
freeStringTable(currentTabVarName, currentNbVarNames);
712
} else if(!strcmp(elem, "User")) {
713
ptr = xp_get_string("variables", "User");
715
char ** currentTabVarName = NULL;
716
int currentNbVarNames;
718
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
719
for (int i = 0; i < currentNbVarNames; i++) {
720
userVariables->find(currentTabVarName[i], true);
722
freeStringTable(currentTabVarName, currentNbVarNames);
724
} else if(!strcmp(elem, "Reference")) {
725
ptr = xp_get_string("variables", "Reference");
727
char ** currentTabVarName = NULL;
728
int currentNbVarNames;
730
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
731
for (int i = 0; i < currentNbVarNames; i++) {
732
int id = allocVars->find(currentTabVarName[i], false);
734
ERROR("Could not reference non-existant variable '%s'", currentTabVarName[i]);
737
freeStringTable(currentTabVarName, currentNbVarNames);
739
} else if(!strcmp(elem, "DefaultMessage")) {
740
char *id = xp_get_string("id", "DefaultMessage");
741
if(!(ptr = xp_get_cdata())) {
742
ERROR("No CDATA in 'send' section of xml scenario file");
744
char *msg = clean_cdata(ptr);
745
set_default_message(id, msg);
747
/* XXX: This should really be per scenario. */
748
} else if(!strcmp(elem, "label")) {
749
ptr = xp_get_string("id", "label");
750
if (labelMap.find(ptr) != labelMap.end()) {
751
ERROR("The label name '%s' is used twice.", ptr);
753
labelMap[ptr] = messages.size();
755
} else if (!strcmp(elem, "init")) {
756
/* We have an init section, which must be full of nops or labels. */
759
while ((initelem = xp_open_element(nop_cursor++))) {
760
if (!strcmp(initelem, "nop")) {
761
/* We should parse this. */
762
message *nopmsg = new message(initmessages.size(), "scenario initialization");
763
initmessages.push_back(nopmsg);
764
nopmsg->M_type = MSG_TYPE_NOP;
765
getCommonAttributes(nopmsg);
766
} else if (!strcmp(initelem, "label")) {
767
/* Add an init label. */
768
ptr = xp_get_value((char *)"id");
769
if (initLabelMap.find(ptr) != initLabelMap.end()) {
770
ERROR("The label name '%s' is used twice.", ptr);
772
initLabelMap[ptr] = initmessages.size();
774
ERROR("Invalid element in an init stanza: '%s'", initelem);
778
} else { /** Message Case */
779
if (found_timewait) {
780
ERROR("<timewait> can only be the last message in a scenario!\n");
782
message *curmsg = new message(messages.size(), name ? name : "unknown scenario");
783
messages.push_back(curmsg);
785
if(!strcmp(elem, "send")) {
786
checkOptionalRecv(elem, scenario_file_cursor);
787
curmsg->M_type = MSG_TYPE_SEND;
788
/* Sent messages descriptions */
789
if(!(ptr = xp_get_cdata())) {
790
ERROR("No CDATA in 'send' section of xml scenario file");
793
int removed_clrf = 0;
794
char * msg = clean_cdata(ptr, &removed_clrf);
796
L_content_length = xp_get_content_length(msg);
797
switch (L_content_length) {
799
// the msg does not contain content-length field
802
curmsg -> content_length_flag =
803
message::ContentLengthValueZero; // Initialize to No present
806
curmsg -> content_length_flag =
807
message::ContentLengthValueNoZero; // Initialize to No present
811
if((msg[strlen(msg) - 1] != '\n') && (removed_clrf)) {
816
curmsg -> send_scheme = new SendingMessage(this, msg);
819
// If this is a request we are sending, then store our transaction/method matching information.
820
if (!curmsg->send_scheme->isResponse()) {
821
char *method = curmsg->send_scheme->getMethod();
822
bool isInvite = !strcmp(method, "INVITE");
823
bool isAck = !strcmp(method, "ACK");
825
if ((ptr = xp_get_value("start_txn"))) {
827
ERROR("An ACK message can not start a transaction!");
829
curmsg->start_txn = get_txn(ptr, "start transaction", true, isInvite, false);
830
} else if ((ptr = xp_get_value("ack_txn"))) {
832
ERROR("The ack_txn attribute is valid only for ACK messages!");
834
curmsg->ack_txn = get_txn(ptr, "ack transaction", false, false, true);
836
int len = method_list ? strlen(method_list) : 0;
837
method_list = (char *)realloc(method_list, len + strlen(method) + 1);
839
ERROR_NO("Out of memory allocating method_list!");
841
strcpy(method_list + len, method);
844
if ((ptr = xp_get_value("start_txn"))) {
845
ERROR("Responses can not start a transaction");
847
if ((ptr = xp_get_value("ack_txn"))) {
848
ERROR("Responses can not ACK a transaction");
852
if ((ptr = xp_get_value("response_txn"))) {
853
ERROR("response_txn can only be used for recieved messages.");
856
curmsg -> retrans_delay = xp_get_long("retrans", "retransmission timer", 0);
857
curmsg -> timeout = xp_get_long("timeout", "message send timeout", 0);
858
} else if(!strcmp(elem, (char *)"recv")) {
859
curmsg->M_type = MSG_TYPE_RECV;
860
/* Received messages descriptions */
861
if((ptr = xp_get_value((char *)"response"))) {
862
curmsg ->recv_response = get_long(ptr, "response code");
864
curmsg->recv_response_for_cseq_method_list = strdup(method_list);
866
if ((ptr = xp_get_value("response_txn"))) {
867
curmsg->response_txn = get_txn(ptr, "transaction response", false, false, false);
871
if((ptr = xp_get_value((char *)"request"))) {
872
curmsg -> recv_request = strdup(ptr);
873
if ((ptr = xp_get_value("response_txn"))) {
874
ERROR("response_txn can only be used for recieved responses.");
878
curmsg->optional = xp_get_optional("optional", "recv");
879
last_recv_optional = curmsg->optional;
880
curmsg->advance_state = xp_get_bool("advance_state", "recv", true);
881
if (!curmsg->advance_state && curmsg->optional == OPTIONAL_FALSE) {
882
ERROR("advance_state is allowed only for optional messages (index = %d)\n", messages.size() - 1);
885
if (0 != (ptr = xp_get_value((char *)"regexp_match"))) {
886
if(!strcmp(ptr, "true")) {
887
curmsg -> regexp_match = 1;
891
curmsg->timeout = xp_get_long("timeout", "message timeout", 0);
893
/* record the route set */
894
/* TODO disallow optional and rrs to coexist? */
895
if((ptr = xp_get_value((char *)"rrs"))) {
896
curmsg -> bShouldRecordRoutes = get_bool(ptr, "record route set");
899
/* record the authentication credentials */
900
if((ptr = xp_get_value((char *)"auth"))) {
901
bool temp = get_bool(ptr, "message authentication");
903
curmsg -> bShouldAuthenticate = temp;
906
ERROR("Authentication requires OpenSSL support!");
910
} else if(!strcmp(elem, "pause") || !strcmp(elem, "timewait")) {
911
checkOptionalRecv(elem, scenario_file_cursor);
912
curmsg->M_type = MSG_TYPE_PAUSE;
913
if (!strcmp(elem, "timewait")) {
914
curmsg->timewait = true;
915
found_timewait = true;
919
if ((var = xp_get_var("variable", "pause", -1)) != -1) {
920
curmsg->pause_variable = var;
922
CSample *distribution = parse_distribution(true);
924
bool sanity_check = xp_get_bool("sanity_check", "pause", true);
926
double pause_duration = distribution->cdfInv(0.99);
927
if (sanity_check && (pause_duration > INT_MAX)) {
928
char percentile[100];
931
distribution->timeDescr(desc, sizeof(desc));
932
time_string(pause_duration, percentile, sizeof(percentile));
934
ERROR("The distribution %s has a 99th percentile of %s, which is larger than INT_MAX. You should chose different parameters.", desc, percentile);
937
curmsg->pause_distribution = distribution;
938
/* Update scenario duration with max duration */
939
duration += (int)pause_duration;
942
else if(!strcmp(elem, "nop")) {
943
checkOptionalRecv(elem, scenario_file_cursor);
944
/* Does nothing at SIP level. This message type can be used to handle
945
* actions, increment counters, or for RTDs. */
946
curmsg->M_type = MSG_TYPE_NOP;
948
else if(!strcmp(elem, "recvCmd")) {
949
curmsg->M_type = MSG_TYPE_RECVCMD;
950
curmsg->optional = xp_get_optional("optional", "recv");
951
last_recv_optional = curmsg->optional;
953
/* 3pcc extended mode */
954
if((ptr = xp_get_value((char *)"src"))) {
955
curmsg ->peer_src = strdup(ptr);
956
} else if (extendedTwinSippMode) {
957
ERROR("You must specify a 'src' for recvCmd when using extended 3pcc mode!");
959
} else if(!strcmp(elem, "sendCmd")) {
960
checkOptionalRecv(elem, scenario_file_cursor);
961
curmsg->M_type = MSG_TYPE_SENDCMD;
962
/* Sent messages descriptions */
964
/* 3pcc extended mode */
965
if((ptr = xp_get_value((char *)"dest"))) {
967
curmsg ->peer_dest = peer ;
968
peer_map::iterator peer_it;
969
peer_it = peers.find(peer_map::key_type(peer));
970
if(peer_it == peers.end()) /* the peer (slave or master)
971
has not been added in the map
972
(first occurence in the scenario) */
975
infos.peer_socket = 0;
976
strcpy(infos.peer_host, get_peer_addr(peer));
977
peers[std::string(peer)] = infos;
979
} else if (extendedTwinSippMode) {
980
ERROR("You must specify a 'dest' for sendCmd with extended 3pcc mode!");
983
if(!(ptr = xp_get_cdata())) {
984
ERROR("No CDATA in 'sendCmd' section of xml scenario file");
986
char *msg = clean_cdata(ptr);
988
curmsg -> M_sendCmdData = new SendingMessage(this, msg, true /* skip sanity */);
992
ERROR("Unknown element '%s' in xml scenario file", elem);
995
getCommonAttributes(curmsg);
996
} /** end * Message case */
1002
str_int_map::iterator label_it = labelMap.find("_unexp.main");
1003
if (label_it != labelMap.end()) {
1004
unexpected_jump = label_it->second;
1006
unexpected_jump = -1;
1008
retaddr = find_var("_unexp.retaddr", "unexpected return address");
1009
pausedaddr = find_var("_unexp.pausedaddr", "unexpected paused until");
1011
/* Patch up the labels. */
1012
apply_labels(messages, labelMap);
1013
apply_labels(initmessages, initLabelMap);
1015
/* Some post-scenario loading validation. */
1016
stats->validateRtds();
1018
/* Make sure that all variables are used more than once. */
1019
validate_variable_usage();
1021
/* Make sure that all started transactions have responses, and vice versa. */
1022
validate_txn_usage();
1024
if (messages.size() == 0) {
1025
ERROR("Did not find any messages inside of scenario!");
1029
void scenario::runInit() {
1031
if (initmessages.size() > 0) {
1032
initcall = new call(main_scenario, NULL, NULL, "///main-init", 0, false, false, true);
1037
void clear_int_str(int_str_map m) {
1038
for(int_str_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1044
void clear_str_int(str_int_map m) {
1045
for(str_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1050
void clear_int_int(int_int_map m) {
1051
for(int_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1056
scenario::~scenario() {
1057
for (msgvec::iterator i = messages.begin(); i != messages.end(); i++) {
1064
allocVars->putTable();
1067
for (unsigned int i = 0; i < transactions.size(); i++) {
1068
free(transactions[i].name);
1070
transactions.clear();
1072
clear_str_int(labelMap);
1073
clear_str_int(initLabelMap);
1074
clear_str_int(txnMap);
1077
CSample *parse_distribution(bool oldstyle = false) {
1078
CSample *distribution;
1082
if(!(distname = xp_get_value("distribution"))) {
1084
ERROR("statistically distributed actions or pauses requires 'distribution' parameter");
1086
if ((ptr = xp_get_value("normal"))) {
1087
distname = "normal";
1088
} else if ((ptr = xp_get_value("exponential"))) {
1089
distname = "exponential";
1090
} else if ((ptr = xp_get_value("lognormal"))) {
1091
distname = "lognormal";
1092
} else if ((ptr = xp_get_value("weibull"))) {
1093
distname = "weibull";
1094
} else if ((ptr = xp_get_value("pareto"))) {
1095
distname = "pareto";
1096
} else if ((ptr = xp_get_value("gamma"))) {
1098
} else if ((ptr = xp_get_value("min"))) {
1099
distname = "uniform";
1100
} else if ((ptr = xp_get_value("max"))) {
1101
distname = "uniform";
1102
} else if ((ptr = xp_get_value("milliseconds"))) {
1103
double val = get_double(ptr, "Pause milliseconds");
1104
return new CFixed(val);
1106
return new CDefaultPause();
1110
if (!strcmp(distname, "fixed")) {
1111
double value = xp_get_double("value", "Fixed distribution");
1112
distribution = new CFixed(value);
1113
} else if (!strcmp(distname, "uniform")) {
1114
double min = xp_get_double("min", "Uniform distribution");
1115
double max = xp_get_double("max", "Uniform distribution");
1116
distribution = new CUniform(min, max);
1117
} else if (!strcmp(distname, "normal")) {
1118
double mean = xp_get_double("mean", "Normal distribution");
1119
double stdev = xp_get_double("stdev", "Normal distribution");
1120
distribution = new CNormal(mean, stdev);
1121
} else if (!strcmp(distname, "lognormal")) {
1122
double mean = xp_get_double("mean", "Lognormal distribution");
1123
double stdev = xp_get_double("stdev", "Lognormal distribution");
1124
distribution = new CLogNormal(mean, stdev);
1125
} else if (!strcmp(distname, "exponential")) {
1126
double mean = xp_get_double("mean", "Exponential distribution");
1127
distribution = new CExponential(mean);
1128
} else if (!strcmp(distname, "weibull")) {
1129
double lambda = xp_get_double("lambda", "Weibull distribution");
1130
double k = xp_get_double("k", "Weibull distribution");
1131
distribution = new CWeibull(lambda, k);
1132
} else if (!strcmp(distname, "pareto")) {
1133
double k = xp_get_double("k", "Pareto distribution");
1134
double xsubm = xp_get_double("x_m", "Pareto distribution");
1135
distribution = new CPareto(k, xsubm);
1136
} else if (!strcmp(distname, "gpareto")) {
1137
double shape = xp_get_double("shape", "Generalized Pareto distribution");
1138
double scale = xp_get_double("scale", "Generalized Pareto distribution");
1139
double location = xp_get_double("location", "Generalized Pareto distribution");
1140
distribution = new CGPareto(shape, scale, location);
1141
} else if (!strcmp(distname, "gamma")) {
1142
double k = xp_get_double("k", "Gamma distribution");
1143
double theta = xp_get_double("theta", "Gamma distribution");
1144
distribution = new CGamma(k, theta);
1145
} else if (!strcmp(distname, "negbin")) {
1146
double n = xp_get_double("n", "Negative Binomial distribution");
1147
double p = xp_get_double("p", "Negative Binomial distribution");
1148
distribution = new CNegBin(n, p);
1150
ERROR("Unknown distribution: %s\n", ptr);
1153
return distribution;
1158
/* 3pcc extended mode:
1159
get the correspondances between
1160
slave and master names and their
1163
void parse_slave_cfg()
1166
char line[MAX_PEER_SIZE];
1171
f = fopen(slave_cfg_file, "r");
1173
while (fgets(line, MAX_PEER_SIZE, f) != NULL)
1175
if((temp_peer = strtok(line, ";"))) {
1176
if((peer_host = (char *) malloc(MAX_PEER_SIZE))){
1177
if((temp_host = strtok(NULL, ";"))){
1178
strcpy(peer_host, temp_host);
1179
peer_addrs[std::string(temp_peer)] = peer_host;
1182
ERROR("Cannot allocate memory!\n");
1187
ERROR("Can not open slave_cfg file %s\n", slave_cfg_file);
1192
// Determine in which mode the sipp tool has been
1193
// launched (client, server, 3pcc client, 3pcc server, 3pcc extended master or slave)
1194
void scenario::computeSippMode()
1196
bool isRecvCmdFound = false;
1197
bool isSendCmdFound = false;
1201
thirdPartyMode = MODE_3PCC_NONE;
1203
assert(messages.size() > 0);
1205
for(unsigned int i=0; i<messages.size(); i++)
1207
switch(messages[i]->M_type)
1209
case MSG_TYPE_PAUSE:
1211
/* Allow pauses or nops to go first. */
1214
if (sendMode == -1) {
1215
sendMode = MODE_CLIENT;
1217
if (creationMode == -1) {
1218
creationMode = MODE_CLIENT;
1223
if (sendMode == -1) {
1224
sendMode = MODE_SERVER;
1226
if (creationMode == -1) {
1227
creationMode = MODE_SERVER;
1230
case MSG_TYPE_SENDCMD:
1231
isSendCmdFound = true;
1232
if (creationMode == -1) {
1233
creationMode = MODE_CLIENT;
1235
if(!isRecvCmdFound) {
1236
if (creationMode == MODE_SERVER) {
1238
* If it is a server already, then start it in
1239
* 3PCC A passive mode
1242
thirdPartyMode = MODE_3PCC_A_PASSIVE;
1243
}else if (extendedTwinSippMode){
1244
thirdPartyMode = MODE_MASTER_PASSIVE;
1248
thirdPartyMode = MODE_3PCC_CONTROLLER_A;
1249
}else if (extendedTwinSippMode){
1250
thirdPartyMode = MODE_MASTER;
1253
if((thirdPartyMode == MODE_MASTER_PASSIVE || thirdPartyMode == MODE_MASTER) && !master_name){
1254
ERROR("Inconsistency between command line and scenario: master scenario but -master option not set\n");
1256
if(!twinSippMode && !extendedTwinSippMode)
1257
ERROR("sendCmd message found in scenario but no twin sipp"
1258
" address has been passed! Use -3pcc option or 3pcc extended mode.\n");
1262
case MSG_TYPE_RECVCMD:
1263
if (creationMode == -1) {
1264
creationMode = MODE_SERVER;
1266
isRecvCmdFound = true;
1270
thirdPartyMode = MODE_3PCC_CONTROLLER_B;
1271
} else if(extendedTwinSippMode){
1272
thirdPartyMode = MODE_SLAVE;
1274
ERROR("Inconsistency between command line and scenario: slave scenario but -slave option not set\n");
1276
thirdPartyMode = MODE_SLAVE;
1279
if(!twinSippMode && !extendedTwinSippMode)
1280
ERROR("recvCmd message found in scenario but no "
1281
"twin sipp address has been passed! Use "
1289
if(creationMode == -1)
1290
ERROR("Unable to determine creation mode of the tool (server, client)\n");
1292
ERROR("Unable to determine send mode of the tool (server, client)\n");
1295
void scenario::handle_rhs(CAction *tmpAction, char *what) {
1296
if (xp_get_value("value")) {
1297
tmpAction->setDoubleValue(xp_get_double("value", what));
1298
if (xp_get_value("variable")) {
1299
ERROR("Value and variable are mutually exclusive for %s action!", what);
1301
} else if (xp_get_value("variable")) {
1302
tmpAction->setVarInId(xp_get_var("variable", what));
1303
if (xp_get_value("value")) {
1304
ERROR("Value and variable are mutually exclusive for %s action!", what);
1307
ERROR("No value or variable defined for %s action!", what);
1311
void scenario::handle_arithmetic(CAction *tmpAction, char *what) {
1312
tmpAction->setVarId(xp_get_var("assign_to", what));
1313
handle_rhs(tmpAction, what);
1316
void scenario::parseAction(CActions *actions) {
1318
unsigned int recvScenarioLen = 0;
1319
char * currentRegExp = NULL;
1320
char * buffer = NULL;
1321
char ** currentTabVarName = NULL;
1322
int currentNbVarNames;
1324
int sub_currentNbVarId;
1326
while((actionElem = xp_open_element(recvScenarioLen))) {
1327
CAction *tmpAction = new CAction(this);
1329
if(!strcmp(actionElem, "ereg")) {
1330
ptr = xp_get_string("regexp", "ereg");
1332
// keeping regexp expression in memory
1333
if(currentRegExp != NULL)
1334
delete[] currentRegExp;
1335
currentRegExp = new char[strlen(ptr)+1];
1336
buffer = new char[strlen(ptr)+1];
1337
xp_replace(ptr, buffer, "<", "<");
1338
xp_replace(buffer, currentRegExp, ">", ">");
1341
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_REGEXP);
1343
// warning - although these are detected for both msg and hdr
1344
// they are only implemented for search_in="hdr"
1345
tmpAction->setCaseIndep(xp_get_bool("case_indep", "ereg", false));
1346
tmpAction->setHeadersOnly(xp_get_bool("start_line", "ereg", false));
1349
if ( 0 != ( ptr = xp_get_value((char *)"search_in") ) ) {
1350
tmpAction->setOccurence(1);
1352
if ( 0 == strcmp(ptr, (char *)"msg") ) {
1353
tmpAction->setLookingPlace(CAction::E_LP_MSG);
1354
tmpAction->setLookingChar (NULL);
1355
} else if ( 0 == strcmp(ptr, (char *)"body") ) {
1356
tmpAction->setLookingPlace(CAction::E_LP_BODY);
1357
tmpAction->setLookingChar (NULL);
1358
} else if (!strcmp(ptr, (char *)"var")) {
1359
tmpAction->setVarInId(xp_get_var("variable", "ereg"));
1360
tmpAction->setLookingPlace(CAction::E_LP_VAR);
1361
} else if (!strcmp(ptr, (char *)"hdr")) {
1362
ptr = xp_get_value((char *)"header");
1363
if (!ptr || !strlen(ptr)) {
1364
ERROR("search_in=\"hdr\" requires header field");
1366
tmpAction->setLookingPlace(CAction::E_LP_HDR);
1367
tmpAction->setLookingChar(ptr);
1368
if (0 != (ptr = xp_get_value((char *)"occurence"))) {
1369
tmpAction->setOccurence (atol(ptr));
1371
if (0 != (ptr = xp_get_value((char *)"occurrence"))) {
1372
tmpAction->setOccurence (atol(ptr));
1375
ERROR("Unknown search_in value %s", ptr);
1378
tmpAction->setLookingPlace(CAction::E_LP_MSG);
1379
tmpAction->setLookingChar(NULL);
1380
} // end if-else search_in
1382
if (xp_get_value("check_it")) {
1383
tmpAction->setCheckIt(xp_get_bool("check_it", "ereg", false));
1384
if (xp_get_value("check_it_inverse")) {
1385
ERROR("Can not have both check_it and check_it_inverse for ereg!");
1388
tmpAction->setCheckItInverse(xp_get_bool("check_it_inverse", "ereg", false));
1391
if (!(ptr = xp_get_value((char *) "assign_to"))) {
1392
ERROR("assign_to value is missing");
1395
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
1397
int varId = get_var(currentTabVarName[0], "assign_to");
1398
tmpAction->setVarId(varId);
1400
tmpAction->setRegExp(currentRegExp);
1401
if (currentNbVarNames > 1 ) {
1402
sub_currentNbVarId = currentNbVarNames - 1 ;
1403
tmpAction->setNbSubVarId(sub_currentNbVarId);
1405
for(int i=1; i<= sub_currentNbVarId; i++) {
1406
int varId = get_var(currentTabVarName[i], "sub expression assign_to");
1407
tmpAction->setSubVarId(varId);
1411
freeStringTable(currentTabVarName, currentNbVarNames);
1413
if(currentRegExp != NULL) {
1414
delete[] currentRegExp;
1416
currentRegExp = NULL;
1417
} /* end !strcmp(actionElem, "ereg") */ else if(!strcmp(actionElem, "log")) {
1418
tmpAction->setMessage(xp_get_string("message", "log"));
1419
tmpAction->setActionType(CAction::E_AT_LOG_TO_FILE);
1420
} else if(!strcmp(actionElem, "warning")) {
1421
tmpAction->setMessage(xp_get_string("message", "warning"));
1422
tmpAction->setActionType(CAction::E_AT_LOG_WARNING);
1423
} else if(!strcmp(actionElem, "error")) {
1424
tmpAction->setMessage(xp_get_string("message", "error"));
1425
tmpAction->setActionType(CAction::E_AT_LOG_ERROR);
1426
} else if(!strcmp(actionElem, "assign")) {
1427
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_VALUE);
1428
handle_arithmetic(tmpAction, "assign");
1429
} else if(!strcmp(actionElem, "assignstr")) {
1430
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_STRING);
1431
tmpAction->setVarId(xp_get_var("assign_to", "assignstr"));
1432
tmpAction->setMessage(xp_get_string("value", "assignstr"));
1433
} else if(!strcmp(actionElem, "gettimeofday")) {
1434
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_GETTIMEOFDAY);
1436
if (!(ptr = xp_get_value((char *) "assign_to"))) {
1437
ERROR("assign_to value is missing");
1439
createStringTable(ptr, ¤tTabVarName, ¤tNbVarNames);
1440
if (currentNbVarNames != 2 ) {
1441
ERROR("The gettimeofday action requires two output variables!");
1443
tmpAction->setNbSubVarId(1);
1445
int varId = get_var(currentTabVarName[0], "gettimeofday seconds assign_to");
1446
tmpAction->setVarId(varId);
1447
varId = get_var(currentTabVarName[1], "gettimeofday useconds assign_to");
1448
tmpAction->setSubVarId(varId);
1450
freeStringTable(currentTabVarName, currentNbVarNames);
1451
} else if(!strcmp(actionElem, "index")) {
1452
tmpAction->setVarId(xp_get_var("assign_to", "index"));
1453
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_INDEX);
1454
} else if(!strcmp(actionElem, "jump")) {
1455
tmpAction->setActionType(CAction::E_AT_JUMP);
1456
handle_rhs(tmpAction, "jump");
1457
} else if(!strcmp(actionElem, "pauserestore")) {
1458
tmpAction->setActionType(CAction::E_AT_PAUSE_RESTORE);
1459
handle_rhs(tmpAction, "pauserestore");
1460
} else if(!strcmp(actionElem, "add")) {
1461
tmpAction->setActionType(CAction::E_AT_VAR_ADD);
1462
handle_arithmetic(tmpAction, "add");
1463
} else if(!strcmp(actionElem, "subtract")) {
1464
tmpAction->setActionType(CAction::E_AT_VAR_SUBTRACT);
1465
handle_arithmetic(tmpAction, "subtract");
1466
} else if(!strcmp(actionElem, "multiply")) {
1467
tmpAction->setActionType(CAction::E_AT_VAR_MULTIPLY);
1468
handle_arithmetic(tmpAction, "multiply");
1469
} else if(!strcmp(actionElem, "divide")) {
1470
tmpAction->setActionType(CAction::E_AT_VAR_DIVIDE);
1471
handle_arithmetic(tmpAction, "divide");
1472
if (tmpAction->getVarInId() == 0) {
1473
if (tmpAction->getDoubleValue() == 0.0) {
1474
ERROR("divide actions can not have a value of zero!");
1477
} else if(!strcmp(actionElem, "sample")) {
1478
tmpAction->setVarId(xp_get_var("assign_to", "sample"));
1479
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_SAMPLE);
1480
tmpAction->setDistribution(parse_distribution());
1481
} else if(!strcmp(actionElem, "todouble")) {
1482
tmpAction->setActionType(CAction::E_AT_VAR_TO_DOUBLE);
1483
tmpAction->setVarId(xp_get_var("assign_to", "todouble"));
1484
tmpAction->setVarInId(xp_get_var("variable", "todouble"));
1485
} else if(!strcmp(actionElem, "test")) {
1486
tmpAction->setVarId(xp_get_var("assign_to", "test"));
1487
tmpAction->setVarInId(xp_get_var("variable", "test"));
1488
if (xp_get_value("value")) {
1489
tmpAction->setDoubleValue(xp_get_double("value", "test"));
1490
if (xp_get_value("variable2")) {
1491
ERROR("Can not have both a value and a variable2 for test!");
1494
tmpAction->setVarIn2Id(xp_get_var("variable2", "test"));
1496
tmpAction->setActionType(CAction::E_AT_VAR_TEST);
1497
ptr = xp_get_string("compare", "test");
1498
if (!strcmp(ptr, "equal")) {
1499
tmpAction->setComparator(CAction::E_C_EQ);
1500
} else if (!strcmp(ptr, "not_equal")) {
1501
tmpAction->setComparator(CAction::E_C_NE);
1502
} else if (!strcmp(ptr, "greater_than")) {
1503
tmpAction->setComparator(CAction::E_C_GT);
1504
} else if (!strcmp(ptr, "less_than")) {
1505
tmpAction->setComparator(CAction::E_C_LT);
1506
} else if (!strcmp(ptr, "greater_than_equal")) {
1507
tmpAction->setComparator(CAction::E_C_GEQ);
1508
} else if (!strcmp(ptr, "less_than_equal")) {
1509
tmpAction->setComparator(CAction::E_C_LEQ);
1511
ERROR("Invalid 'compare' parameter: %s", ptr);
1514
} else if(!strcmp(actionElem, "verifyauth")) {
1516
tmpAction->setVarId(xp_get_var("assign_to", "verifyauth"));
1517
tmpAction->setMessage(xp_get_string("username", "verifyauth"), 0);
1518
tmpAction->setMessage(xp_get_string("password", "verifyauth"), 1);
1519
tmpAction->setActionType(CAction::E_AT_VERIFY_AUTH);
1521
ERROR("The verifyauth action requires OpenSSL support.");
1523
} else if(!strcmp(actionElem, "lookup")) {
1524
tmpAction->setVarId(xp_get_var("assign_to", "lookup"));
1525
tmpAction->setMessage(xp_get_string("file", "lookup"), 0);
1526
tmpAction->setMessage(xp_get_string("key", "lookup"), 1);
1527
tmpAction->setActionType(CAction::E_AT_LOOKUP);
1528
} else if(!strcmp(actionElem, "insert")) {
1529
tmpAction->setMessage(xp_get_string("file", "insert"), 0);
1530
tmpAction->setMessage(xp_get_string("value", "insert"), 1);
1531
tmpAction->setActionType(CAction::E_AT_INSERT);
1532
} else if(!strcmp(actionElem, "replace")) {
1533
tmpAction->setMessage(xp_get_string("file", "replace"), 0);
1534
tmpAction->setMessage(xp_get_string("line", "replace"), 1);
1535
tmpAction->setMessage(xp_get_string("value", "replace"), 2);
1536
tmpAction->setActionType(CAction::E_AT_REPLACE);
1537
} else if(!strcmp(actionElem, "setdest")) {
1538
tmpAction->setMessage(xp_get_string("host", actionElem), 0);
1539
tmpAction->setMessage(xp_get_string("port", actionElem), 1);
1540
tmpAction->setMessage(xp_get_string("protocol", actionElem), 2);
1541
tmpAction->setActionType(CAction::E_AT_SET_DEST);
1542
} else if(!strcmp(actionElem, "closecon")) {
1543
tmpAction->setActionType(CAction::E_AT_CLOSE_CON);
1544
} else if(!strcmp(actionElem, "strcmp")) {
1545
tmpAction->setVarId(xp_get_var("assign_to", "strcmp"));
1546
tmpAction->setVarInId(xp_get_var("variable", "strcmp"));
1547
if (xp_get_value("value")) {
1548
tmpAction->setStringValue(xp_get_string("value", "strcmp"));
1549
if (xp_get_value("variable2")) {
1550
ERROR("Can not have both a value and a variable2 for strcmp!");
1553
tmpAction->setVarIn2Id(xp_get_var("variable2", "strcmp"));
1555
tmpAction->setActionType(CAction::E_AT_VAR_STRCMP);
1556
} else if(!strcmp(actionElem, "trim")) {
1557
tmpAction->setVarId(xp_get_var("assign_to", "trim"));
1558
tmpAction->setActionType(CAction::E_AT_VAR_TRIM);
1559
} else if(!strcmp(actionElem, "exec")) {
1560
if((ptr = xp_get_value((char *)"command"))) {
1561
tmpAction->setActionType(CAction::E_AT_EXECUTE_CMD);
1562
tmpAction->setMessage(ptr);
1563
} /* end (ptr = xp_get_value("command") */ else if((ptr = xp_get_value((char *)"int_cmd"))) {
1564
CAction::T_IntCmdType type(CAction::E_INTCMD_STOPCALL); /* assume the default */
1566
if (!strcmp(ptr, "stop_now")) {
1567
type = CAction::E_INTCMD_STOP_NOW;
1568
} else if (!strcmp(ptr, "stop_gracefully")) {
1569
type = CAction::E_INTCMD_STOP_ALL;
1570
} else if (!strcmp(ptr, "stop_call")) {
1571
type = CAction::E_INTCMD_STOPCALL;
1574
/* the action is well formed, adding it in the */
1575
/* tmpActionTable */
1576
tmpAction->setActionType(CAction::E_AT_EXEC_INTCMD);
1577
tmpAction->setIntCmd(type);
1579
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
1580
tmpAction->setPcapArgs(ptr);
1581
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_AUDIO);
1583
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
1584
tmpAction->setPcapArgs(ptr);
1585
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_VIDEO);
1588
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
1589
ERROR("play_pcap_audio requires pcap support! Please recompile SIPp");
1590
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
1591
ERROR("play_pcap_video requires pcap support! Please recompile SIPp");
1594
ERROR("illegal <exec> in the scenario\n");
1597
ERROR("Unknown action: %s", actionElem);
1600
/* If the action was not well-formed, there should have already been an
1601
* ERROR declaration, thus it is safe to add it here at the end of the loop. */
1602
actions->setAction(tmpAction);
1609
// Action list for the message indexed by message_index in
1611
void scenario::getActionForThisMessage(message *message)
1615
if(!(actionElem = xp_open_element(0))) {
1618
if(strcmp(actionElem, "action")) {
1622
/* We actually have an action element. */
1623
if(message->M_actions != NULL) {
1624
ERROR("Duplicate action for %s index %d", message->desc, message->index);
1626
message->M_actions = new CActions();
1628
parseAction(message->M_actions);
1632
void scenario::getBookKeeping(message *message) {
1635
if((ptr = xp_get_value((char *)"rtd"))) {
1636
message -> stop_rtd = get_rtd(ptr, false);
1638
if ((ptr = xp_get_value((char *)"repeat_rtd"))) {
1639
if (message -> stop_rtd) {
1640
message-> repeat_rtd = get_bool(ptr, "repeat_rtd");
1642
ERROR("There is a repeat_rtd element without an rtd element");
1646
if((ptr = xp_get_value((char *)"start_rtd"))) {
1647
message -> start_rtd = get_rtd(ptr, true);
1650
if((ptr = xp_get_value((char *)"counter"))) {
1651
message -> counter = get_counter(ptr, "counter");
1655
void scenario::getCommonAttributes(message *message) {
1658
getBookKeeping(message);
1659
getActionForThisMessage(message);
1661
if((ptr = xp_get_value((char *)"lost"))) {
1662
message -> lost = get_double(ptr, "lost percentage");
1666
if((ptr = xp_get_value((char *)"crlf"))) {
1667
message -> crlf = 1;
1670
if (xp_get_value("hiderest")) {
1671
hidedefault = xp_get_bool("hiderest", "hiderest");
1673
message -> hide = xp_get_bool("hide", "hide", hidedefault);
1674
if((ptr = xp_get_value((char *)"display"))) {
1675
message -> display_str = strdup(ptr);
1678
message -> condexec = xp_get_var("condexec", "condexec variable", -1);
1679
message -> condexec_inverse = xp_get_bool("condexec_inverse", "condexec_inverse", false);
1681
if ((ptr = xp_get_value((char *)"next"))) {
1682
if (found_timewait) {
1683
ERROR("next labels are not allowed in <timewait> elements.");
1685
message -> nextLabel = strdup(ptr);
1686
message -> test = xp_get_var("test", "test variable", -1);
1687
if ( 0 != ( ptr = xp_get_value((char *)"chance") ) ) {
1688
float chance = get_double(ptr,"chance");
1689
/* probability of branch to next */
1690
if (( chance < 0.0 ) || (chance > 1.0 )) {
1691
ERROR("Chance %s not in range [0..1]", ptr);
1693
message -> chance = (int)((1.0-chance)*RAND_MAX);
1696
message -> chance = 0; /* always */
1700
if ((ptr = xp_get_value((char *)"ontimeout"))) {
1701
if (found_timewait) {
1702
ERROR("ontimeout labels are not allowed in <timewait> elements.");
1704
message -> onTimeoutLabel = strdup(ptr);
1708
// char* manipulation : create a int[] from a char*
1709
// test first is the char* is formed by int separeted by coma
1710
// and then create the table
1712
int isWellFormed(char * P_listeStr, int * nombre)
1714
char * ptr = P_listeStr;
1719
sizeOf = strlen(P_listeStr);
1720
// getting the number
1723
// is the string well formed ? [0-9] [,]
1725
for(int i=0; i<=sizeOf; i++)
1730
if(isANumber == false)
1756
if(isANumber == false)
1773
int createIntegerTable(char * P_listeStr,
1774
unsigned int ** listeInteger,
1778
char * ptr = P_listeStr;
1779
char * ptr_prev = P_listeStr;
1780
unsigned int current_int;
1783
if(isWellFormed(P_listeStr, sizeOfList) == 1)
1785
(*listeInteger) = new unsigned int[(*sizeOfList)];
1786
while((*ptr) != ('\0'))
1790
sscanf(ptr_prev, "%u", ¤t_int);
1791
if (nb<(*sizeOfList))
1792
(*listeInteger)[nb] = current_int;
1800
sscanf(ptr_prev, "%u", ¤t_int);
1801
if (nb<(*sizeOfList))
1802
(*listeInteger)[nb] = current_int;
1810
int createStringTable(char * inputString, char *** stringList, int *sizeOfList)
1821
char *p = strchr(inputString, ',');
1826
*stringList = (char **)realloc(*stringList, sizeof(char *) * (*sizeOfList + 1));
1827
(*stringList)[*sizeOfList] = strdup(inputString);
1832
while (inputString);
1837
void freeStringTable(char ** stringList, int sizeOfList) {
1838
for (int i = 0; i < sizeOfList; i++) {
1839
free(stringList[i]);
1844
/* These are the names of the scenarios, they must match the default_scenario table. */
1845
char *scenario_table[] = {
1859
int find_scenario(const char *scenario) {
1861
max = sizeof(scenario_table)/sizeof(scenario_table[0]);
1863
for (i = 0; i < max; i++) {
1864
if (!strcmp(scenario_table[i], scenario)) {
1869
ERROR("Invalid default scenario name '%s'.\n", scenario);
1873
// TIP: to integrate an existing XML scenario, use the following sed line:
1874
// cat ../3pcc-controller-B.xml | sed -e 's/\"/\\\"/g' -e 's/\(.*\)/\"\1\\n\"/'
1875
char * default_scenario [] = {
1876
/************* Default_scenario[0] ***************/
1878
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
1879
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
1881
"<!-- This program is free software; you can redistribute it and/or -->\n"
1882
"<!-- modify it under the terms of the GNU General Public License as -->\n"
1883
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
1884
"<!-- License, or (at your option) any later version. -->\n"
1886
"<!-- This program is distributed in the hope that it will be useful, -->\n"
1887
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
1888
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
1889
"<!-- GNU General Public License for more details. -->\n"
1891
"<!-- You should have received a copy of the GNU General Public License -->\n"
1892
"<!-- along with this program; if not, write to the -->\n"
1893
"<!-- Free Software Foundation, Inc., -->\n"
1894
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
1896
"<!-- Sipp default 'uac' scenario. -->\n"
1899
"<scenario name=\"Basic Sipstone UAC\">\n"
1900
" <!-- In client mode (sipp placing calls), the Call-ID MUST be -->\n"
1901
" <!-- generated by sipp. To do so, use [call_id] keyword. -->\n"
1902
" <send retrans=\"500\">\n"
1905
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1906
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1907
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1908
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
1909
" Call-ID: [call_id]\n"
1911
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1912
" Max-Forwards: 70\n"
1913
" Subject: Performance Test\n"
1914
" Content-Type: application/sdp\n"
1915
" Content-Length: [len]\n"
1918
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
1920
" c=IN IP[media_ip_type] [media_ip]\n"
1922
" m=audio [media_port] RTP/AVP 0\n"
1923
" a=rtpmap:0 PCMU/8000\n"
1928
" <recv response=\"100\"\n"
1929
" optional=\"true\">\n"
1932
" <recv response=\"180\" optional=\"true\">\n"
1935
" <recv response=\"183\" optional=\"true\">\n"
1938
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
1939
" <!-- are saved and used for following messages sent. Useful to test -->\n"
1940
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
1941
" <recv response=\"200\" rtd=\"true\">\n"
1944
" <!-- Packet lost can be simulated in any send/recv message by -->\n"
1945
" <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent. -->\n"
1949
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1950
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1951
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1952
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1953
" Call-ID: [call_id]\n"
1955
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1956
" Max-Forwards: 70\n"
1957
" Subject: Performance Test\n"
1958
" Content-Length: 0\n"
1963
" <!-- This delay can be customized by the -d command-line option -->\n"
1964
" <!-- or by adding a 'milliseconds = \"value\"' option here. -->\n"
1967
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
1968
" <send retrans=\"500\">\n"
1971
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1972
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1973
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1974
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1975
" Call-ID: [call_id]\n"
1977
" Contact: sip:sipp@[local_ip]:[local_port]\n"
1978
" Max-Forwards: 70\n"
1979
" Subject: Performance Test\n"
1980
" Content-Length: 0\n"
1985
" <recv response=\"200\" crlf=\"true\">\n"
1988
" <!-- definition of the response time repartition table (unit is ms) -->\n"
1989
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
1991
" <!-- definition of the call length repartition table (unit is ms) -->\n"
1992
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
1998
/************* Default_scenario[1] ***************/
2000
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2001
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2003
"<!-- This program is free software; you can redistribute it and/or -->\n"
2004
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2005
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2006
"<!-- License, or (at your option) any later version. -->\n"
2008
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2009
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2010
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2011
"<!-- GNU General Public License for more details. -->\n"
2013
"<!-- You should have received a copy of the GNU General Public License -->\n"
2014
"<!-- along with this program; if not, write to the -->\n"
2015
"<!-- Free Software Foundation, Inc., -->\n"
2016
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2018
"<!-- Sipp default 'uas' scenario. -->\n"
2021
"<scenario name=\"Basic UAS responder\">\n"
2022
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
2023
" <!-- are saved and used for following messages sent. Useful to test -->\n"
2024
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
2025
" <recv request=\"INVITE\" crlf=\"true\">\n"
2028
" <!-- The '[last_*]' keyword is replaced automatically by the -->\n"
2029
" <!-- specified header if it was present in the last message received -->\n"
2030
" <!-- (except if it was a retransmission). If the header was not -->\n"
2031
" <!-- present or if no message has been received, the '[last_*]' -->\n"
2032
" <!-- keyword is discarded, and all bytes until the end of the line -->\n"
2033
" <!-- are also discarded. -->\n"
2035
" <!-- If the specified header was present several times in the -->\n"
2036
" <!-- message, all occurences are concatenated (CRLF seperated) -->\n"
2037
" <!-- to be used in place of the '[last_*]' keyword. -->\n"
2042
" SIP/2.0 180 Ringing\n"
2045
" [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2046
" [last_Call-ID:]\n"
2048
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2049
" Content-Length: 0\n"
2054
" <send retrans=\"500\">\n"
2060
" [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2061
" [last_Call-ID:]\n"
2063
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2064
" Content-Type: application/sdp\n"
2065
" Content-Length: [len]\n"
2068
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2070
" c=IN IP[media_ip_type] [media_ip]\n"
2072
" m=audio [media_port] RTP/AVP 0\n"
2073
" a=rtpmap:0 PCMU/8000\n"
2078
" <recv request=\"ACK\"\n"
2079
" optional=\"true\"\n"
2084
" <recv request=\"BYE\">\n"
2094
" [last_Call-ID:]\n"
2096
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2097
" Content-Length: 0\n"
2102
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2103
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2104
" <timewait milliseconds=\"4000\"/>\n"
2107
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2108
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2110
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2111
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2116
/************* Default_scenario[2] ***************/
2118
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2119
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2121
"<!-- This program is free software; you can redistribute it and/or -->\n"
2122
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2123
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2124
"<!-- License, or (at your option) any later version. -->\n"
2126
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2127
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2128
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2129
"<!-- GNU General Public License for more details. -->\n"
2131
"<!-- You should have received a copy of the GNU General Public License -->\n"
2132
"<!-- along with this program; if not, write to the -->\n"
2133
"<!-- Free Software Foundation, Inc., -->\n"
2134
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2136
"<!-- Sipp default 'regexp client' scenario. -->\n"
2139
"<scenario name=\"Client with regexp scenario\">\n"
2140
" <send retrans=\"500\">\n"
2143
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2144
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2145
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2146
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2147
" Call-ID: [call_id]\n"
2149
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2150
" Max-Forwards: 70\n"
2151
" Subject: Performance Test\n"
2152
" Content-Type: application/sdp\n"
2153
" Content-Length: [len]\n"
2156
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2158
" c=IN IP[media_ip_type] [media_ip]\n"
2160
" m=audio [media_port] RTP/AVP 0\n"
2161
" a=rtpmap:0 PCMU/8000\n"
2166
" <recv response=\"100\"\n"
2167
" optional=\"true\">\n"
2170
" <recv response=\"180\" optional=\"true\">\n"
2172
" <recv response=\"183\" optional=\"true\">\n"
2175
" <recv response=\"200\" start_rtd=\"true\">\n"
2176
" <!-- Definition of regexp in the action tag. The regexp must follow -->\n"
2177
" <!-- the Posix Extended standard (POSIX 1003.2), see: -->\n"
2179
" <!-- http://www.opengroup.org/onlinepubs/007908799/xbd/re.html -->\n"
2181
" <!-- regexp : Contain the regexp to use for matching the -->\n"
2182
" <!-- received message -->\n"
2183
" <!-- MANDATORY -->\n"
2184
" <!-- search_in : msg (try to match against the entire message) -->\n"
2185
" <!-- : hdr (try to match against a specific SIP header -->\n"
2186
" <!-- (passed in the header tag) -->\n"
2187
" <!-- OPTIONAL - default value : msg -->\n"
2188
" <!-- header : Header to try to match against. -->\n"
2189
" <!-- Only used when the search_in tag is set to hdr -->\n"
2190
" <!-- MANDATORY IF search_in is equal to hdr -->\n"
2191
" <!-- check_it : if set to true, the call is marked as failed if -->\n"
2192
" <!-- the regexp doesn't match. -->\n"
2193
" <!-- OPTIONAL - default value : false -->\n"
2194
" <!-- assign_to : contain the variable id (integer) or a list of -->\n"
2195
" <!-- variable id which will be used to store the -->\n"
2196
" <!-- result of the matching process between the regexp -->\n"
2197
" <!-- and the message. This variable can be re-used at -->\n"
2198
" <!-- a later time in the scenario using '[$n]' syntax -->\n"
2199
" <!-- where n is the variable id. -->\n"
2200
" <!-- MANDATORY -->\n"
2202
" <ereg regexp=\"[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[:][0-9]{1,5}\" \n"
2203
" search_in=\"msg\" \n"
2204
" check_it=\"true\" \n"
2205
" assign_to=\"1\"/>\n"
2206
" <ereg regexp=\".*\" \n"
2207
" search_in=\"hdr\" \n"
2208
" header=\"Contact:\" \n"
2209
" check_it=\"true\" \n"
2210
" assign_to=\"6\"/>\n"
2211
" <ereg regexp=\"o=([[:alnum:]]*) ([[:alnum:]]*) ([[:alnum:]]*)\"\n"
2212
" search_in=\"msg\" \n"
2213
" check_it=\"true\" \n"
2214
" assign_to=\"3,4,5,8\"/>\n"
2220
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2221
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2222
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2223
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2224
" Call-ID: [call_id]\n"
2226
" retrievedIp: [$1]\n"
2227
" retrievedContact:[$6]\n"
2228
" retrievedSdpOrigin:[$3]\n"
2229
" retrievedSdpOrigin-username:[$4]\n"
2230
" retrievedSdpOrigin-session-id:[$5]\n"
2231
" retrievedSdpOrigin-version:[$8]\n"
2232
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2233
" Max-Forwards: 70\n"
2234
" Subject: Performance Test\n"
2235
" Content-Length: 0\n"
2239
" <!-- This delay can be customized by the -d command-line option -->\n"
2240
" <!-- or by adding a 'milliseconds = \"value\"' option here. -->\n"
2241
" <pause milliseconds = \"1000\"/>\n"
2243
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2244
" <send retrans=\"500\">\n"
2247
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2248
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2249
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2250
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2251
" Call-ID: [call_id]\n"
2253
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2254
" Max-Forwards: 70\n"
2255
" Subject: Performance Test\n"
2256
" Content-Length: 0\n"
2261
" <recv response=\"200\" crlf=\"true\" rtd=\"true\">\n"
2264
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2265
" <ResponseTimeRepartition value=\"1000, 1040, 1080, 1120, 1160, 1200\"/>\n"
2267
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2268
" <CallLengthRepartition value=\"1000, 1100, 1200, 1300, 1400\"/>\n"
2273
/************* Default_scenario[3] ***************/
2275
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2276
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2278
"<!-- This program is free software; you can redistribute it and/or -->\n"
2279
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2280
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2281
"<!-- License, or (at your option) any later version. -->\n"
2283
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2284
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2285
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2286
"<!-- GNU General Public License for more details. -->\n"
2288
"<!-- You should have received a copy of the GNU General Public License -->\n"
2289
"<!-- along with this program; if not, write to the -->\n"
2290
"<!-- Free Software Foundation, Inc., -->\n"
2291
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2293
"<!-- 3PCC - Controller - A side -->\n"
2295
"<!-- A Controller B -->\n"
2296
"<!-- |(1) INVITE no SDP | | -->\n"
2297
"<!-- |<==================| | -->\n"
2298
"<!-- |(2) 200 offer1 | | -->\n"
2299
"<!-- |==================>| | -->\n"
2300
"<!-- | |(3) INVITE offer1 | -->\n"
2301
"<!-- | |==================>| -->\n"
2302
"<!-- | |(4) 200 OK answer1 | -->\n"
2303
"<!-- | |<==================| -->\n"
2304
"<!-- | |(5) ACK | -->\n"
2305
"<!-- | |==================>| -->\n"
2306
"<!-- |(6) ACK answer1 | | -->\n"
2307
"<!-- |<==================| | -->\n"
2308
"<!-- |(7) RTP | | -->\n"
2309
"<!-- |.......................................| -->\n"
2312
"<scenario name=\"3PCC Controller - A side\">\n"
2313
" <send retrans=\"500\">\n"
2316
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2317
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2318
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2319
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2320
" Call-ID: [call_id]\n"
2322
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2323
" Max-Forwards: 70\n"
2324
" Subject: Performance Test\n"
2325
" Content-Length: 0\n"
2330
" <recv response=\"100\" optional=\"true\"> </recv>\n"
2331
" <recv response=\"180\" optional=\"true\"> </recv>\n"
2332
" <recv response=\"183\" optional=\"true\"> </recv>\n"
2333
" <recv response=\"200\" crlf=\"true\" start_rtd=\"true\">\n"
2335
" <ereg regexp=\"Content-Type:.*\" \n"
2336
" search_in=\"msg\" \n"
2337
" assign_to=\"1\" /> \n"
2343
" Call-ID: [call_id]\n"
2351
" <ereg regexp=\"Content-Type:.*\" \n"
2352
" search_in=\"msg\" \n"
2353
" assign_to=\"2\" /> \n"
2358
" <send rtd=\"true\">\n"
2361
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2362
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2363
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2364
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2365
" Call-ID: [call_id]\n"
2367
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2368
" Max-Forwards: 70\n"
2369
" Subject: Performance Test\n"
2375
" <pause milliseconds=\"1000\"/>\n"
2377
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2378
" <send retrans=\"500\">\n"
2381
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2382
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2383
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2384
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2385
" Call-ID: [call_id]\n"
2387
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2388
" Max-Forwards: 70\n"
2389
" Subject: Performance Test\n"
2390
" Content-Length: 0\n"
2395
" <recv response=\"200\" crlf=\"true\"> </recv>\n"
2400
/************* Default_scenario[4] ***************/
2402
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2403
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2405
"<!-- This program is free software; you can redistribute it and/or -->\n"
2406
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2407
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2408
"<!-- License, or (at your option) any later version. -->\n"
2410
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2411
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2412
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2413
"<!-- GNU General Public License for more details. -->\n"
2415
"<!-- You should have received a copy of the GNU General Public License -->\n"
2416
"<!-- along with this program; if not, write to the -->\n"
2417
"<!-- Free Software Foundation, Inc., -->\n"
2418
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2420
"<!-- 3PCC - Controller - B side -->\n"
2422
"<!-- A Controller B -->\n"
2423
"<!-- |(1) INVITE no SDP | | -->\n"
2424
"<!-- |<==================| | -->\n"
2425
"<!-- |(2) 200 offer1 | | -->\n"
2426
"<!-- |==================>| | -->\n"
2427
"<!-- | |(3) INVITE offer1 | -->\n"
2428
"<!-- | |==================>| -->\n"
2429
"<!-- | |(4) 200 OK answer1 | -->\n"
2430
"<!-- | |<==================| -->\n"
2431
"<!-- | |(5) ACK | -->\n"
2432
"<!-- | |==================>| -->\n"
2433
"<!-- |(6) ACK answer1 | | -->\n"
2434
"<!-- |<==================| | -->\n"
2435
"<!-- |(7) RTP | | -->\n"
2436
"<!-- |.......................................| -->\n"
2440
"<scenario name=\"3PCC Controller - B side\">\n"
2444
" <ereg regexp=\"Content-Type:.*\" \n"
2445
" search_in=\"msg\" \n"
2446
" assign_to=\"1\" /> \n"
2450
" <send retrans=\"500\">\n"
2453
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2454
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2455
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2456
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
2457
" Call-ID: [call_id]\n"
2459
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2460
" Max-Forwards: 70\n"
2461
" Subject: Performance Test\n"
2467
" <recv response=\"100\" optional=\"true\"> </recv>\n"
2468
" <recv response=\"180\" optional=\"true\"> </recv>\n"
2469
" <recv response=\"183\" optional=\"true\"> </recv>\n"
2470
" <recv response=\"200\" crlf=\"true\">\n"
2472
" <ereg regexp=\"Content-Type:.*\" \n"
2473
" search_in=\"msg\" \n"
2474
" assign_to=\"2\" /> \n"
2479
" <send start_rtd=\"true\">\n"
2482
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2483
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2484
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2485
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2486
" Call-ID: [call_id]\n"
2488
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2489
" Max-Forwards: 70\n"
2490
" Subject: Performance Test\n"
2491
" Content-Length: 0\n"
2498
" Call-ID: [call_id]\n"
2504
" <pause milliseconds=\"1000\"/>\n"
2507
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2508
" <send retrans=\"500\" rtd=\"true\">\n"
2511
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2512
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2513
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2514
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2515
" Call-ID: [call_id]\n"
2517
" Contact: sip:sipp@[local_ip]:[local_port]\n"
2518
" Max-Forwards: 70\n"
2519
" Subject: Performance Test\n"
2520
" Content-Length: 0\n"
2525
" <recv response=\"200\" crlf=\"true\">\n"
2532
/************* Default_scenario[5] ***************/
2534
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2535
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2537
"<!-- This program is free software; you can redistribute it and/or -->\n"
2538
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2539
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2540
"<!-- License, or (at your option) any later version. -->\n"
2542
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2543
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2544
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2545
"<!-- GNU General Public License for more details. -->\n"
2547
"<!-- You should have received a copy of the GNU General Public License -->\n"
2548
"<!-- along with this program; if not, write to the -->\n"
2549
"<!-- Free Software Foundation, Inc., -->\n"
2550
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2552
"<!-- 3PCC - A side emulator -->\n"
2554
"<!-- A Controller B -->\n"
2555
"<!-- |(1) INVITE no SDP | | -->\n"
2556
"<!-- |<==================| | -->\n"
2557
"<!-- |(2) 200 offer1 | | -->\n"
2558
"<!-- |==================>| | -->\n"
2559
"<!-- | |(3) INVITE offer1 | -->\n"
2560
"<!-- | |==================>| -->\n"
2561
"<!-- | |(4) 200 OK answer1 | -->\n"
2562
"<!-- | |<==================| -->\n"
2563
"<!-- | |(5) ACK | -->\n"
2564
"<!-- | |==================>| -->\n"
2565
"<!-- |(6) ACK answer1 | | -->\n"
2566
"<!-- |<==================| | -->\n"
2567
"<!-- |(7) RTP | | -->\n"
2568
"<!-- |.......................................| -->\n"
2572
"<scenario name=\"3PCC A side\">\n"
2573
" <recv request=\"INVITE\" crlf=\"true\">\n"
2582
" [last_To:];tag=[pid]SIPpTag05[call_number]\n"
2583
" [last_Call-ID:]\n"
2585
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2586
" Content-Type: application/sdp\n"
2587
" Content-Length: [len]\n"
2590
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2592
" c=IN IP[media_ip_type] [media_ip]\n"
2594
" m=audio [media_port] RTP/AVP 0\n"
2595
" a=rtpmap:0 PCMU/8000\n"
2600
" <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2602
" <!-- RTP flow starts from here! -->\n"
2604
" <recv request=\"BYE\" crlf=\"true\"> </recv>\n"
2613
" [last_Call-ID:]\n"
2615
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2616
" Content-Length: 0\n"
2621
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2622
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2623
" <timewait milliseconds=\"2000\"/>\n"
2628
/************* Default_scenario[6] ***************/
2630
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2631
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2633
"<!-- This program is free software; you can redistribute it and/or -->\n"
2634
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2635
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2636
"<!-- License, or (at your option) any later version. -->\n"
2638
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2639
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2640
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2641
"<!-- GNU General Public License for more details. -->\n"
2643
"<!-- You should have received a copy of the GNU General Public License -->\n"
2644
"<!-- along with this program; if not, write to the -->\n"
2645
"<!-- Free Software Foundation, Inc., -->\n"
2646
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2648
"<!-- 3PCC - B side emulator -->\n"
2650
"<!-- A Controller B -->\n"
2651
"<!-- |(1) INVITE no SDP | | -->\n"
2652
"<!-- |<==================| | -->\n"
2653
"<!-- |(2) 200 offer1 | | -->\n"
2654
"<!-- |==================>| | -->\n"
2655
"<!-- | |(3) INVITE offer1 | -->\n"
2656
"<!-- | |==================>| -->\n"
2657
"<!-- | |(4) 200 OK answer1 | -->\n"
2658
"<!-- | |<==================| -->\n"
2659
"<!-- | |(5) ACK | -->\n"
2660
"<!-- | |==================>| -->\n"
2661
"<!-- |(6) ACK answer1 | | -->\n"
2662
"<!-- |<==================| | -->\n"
2663
"<!-- |(7) RTP | | -->\n"
2664
"<!-- |.......................................| -->\n"
2669
"<scenario name=\"3PCC B side\">\n"
2670
" <recv request=\"INVITE\" crlf=\"true\"> </recv>\n"
2678
" [last_To:];tag=[pid]SIPpTag06[call_number]\n"
2679
" [last_Call-ID:]\n"
2681
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2682
" Content-Type: application/sdp\n"
2683
" Content-Length: [len]\n"
2686
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2688
" c=IN IP[media_ip_type] [media_ip]\n"
2690
" m=audio [media_port] RTP/AVP 0\n"
2691
" a=rtpmap:0 PCMU/8000\n"
2696
" <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2698
" <!-- RTP flow starts from here! -->\n"
2700
" <recv request=\"BYE\"> </recv>\n"
2709
" [last_Call-ID:]\n"
2711
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2712
" Content-Length: 0\n"
2717
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
2718
" <!-- able to retransmit it if we receive the BYE again. -->\n"
2719
" <timewait milliseconds=\"2000\"/>\n"
2723
/************* Default_scenario[7] ***************/
2725
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2726
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2728
"<!-- This program is free software; you can redistribute it and/or -->\n"
2729
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2730
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2731
"<!-- License, or (at your option) any later version. -->\n"
2733
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2734
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2735
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2736
"<!-- GNU General Public License for more details. -->\n"
2738
"<!-- You should have received a copy of the GNU General Public License -->\n"
2739
"<!-- along with this program; if not, write to the -->\n"
2740
"<!-- Free Software Foundation, Inc., -->\n"
2741
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2743
"<!-- Sipp default 'branchc' scenario. -->\n"
2746
"<scenario name=\"branch_client\">\n"
2747
" <send retrans=\"500\">\n"
2750
" REGISTER sip:CA.cym.com SIP/2.0\n"
2751
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2752
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07[call_number]\n"
2753
" To: ua1 <sip:ua1@nnl.cym:[local_port]>\n"
2754
" Call-ID: [call_id]\n"
2755
" CSeq: 1 REGISTER\n"
2756
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2757
" Content-Length: 0\n"
2763
" <!-- simple case - just jump over a line -->\n"
2764
" <recv response=\"200\" rtd=\"true\" next=\"5\">\n"
2767
" <recv response=\"200\">\n"
2770
" <label id=\"5\"/>\n"
2772
" <send retrans=\"500\">\n"
2775
" INVITE sip:ua2@CA.cym.com SIP/2.0\n"
2776
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2777
" From: ua[call_number] <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2778
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>\n"
2779
" Call-ID: [call_id]\n"
2781
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2782
" Max-Forwards: 70\n"
2783
" Subject: Performance Test\n"
2784
" Content-Type: application/sdp\n"
2785
" Content-Length: [len]\n"
2788
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2790
" c=IN IP[media_ip_type] [media_ip]\n"
2792
" m=audio [media_port] RTP/AVP 0\n"
2793
" a=rtpmap:0 PCMU/8000\n"
2798
" <recv response=\"100\" optional=\"true\">\n"
2801
" <recv response=\"180\" optional=\"true\">\n"
2804
" <recv response=\"183\" optional=\"true\">\n"
2807
" <!-- Do something different on an optional receive -->\n"
2808
" <recv response=\"403\" optional=\"true\" next=\"1\">\n"
2811
" <recv response=\"200\">\n"
2813
" <ereg regexp=\"ua25\"\n"
2814
" search_in=\"hdr\"\n"
2815
" header=\"From: \"\n"
2816
" assign_to=\"8\"/>\n"
2820
" <!-- set variable 8 above on 25th call, send the ACK but skip the pause for it -->\n"
2821
" <send next=\"1\" test=\"8\">\n"
2824
" ACK sip:ua2@CA.cym.com SIP/2.0\n"
2825
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2826
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2827
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2828
" Call-ID: [call_id]\n"
2830
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2831
" Max-Forwards: 70\n"
2832
" Subject: Performance Test\n"
2833
" Content-Length: 0\n"
2838
" <pause milliseconds=\"5000\"/>\n"
2840
" <label id=\"1\"/>\n"
2842
" <send retrans=\"500\">\n"
2845
" BYE sip:ua2@CA.cym.com SIP/2.0\n"
2846
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2847
" From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2848
" To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2849
" Call-ID: [call_id]\n"
2851
" Contact: sip:ua1@[local_ip]:[local_port]\n"
2852
" Max-Forwards: 70\n"
2853
" Subject: Performance Test\n"
2854
" Content-Length: 0\n"
2859
" <recv response=\"200\" crlf=\"true\">\n"
2862
" <pause milliseconds=\"4000\"/>\n"
2864
" <!-- definition of the response time repartition table (unit is ms) -->\n"
2865
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2867
" <!-- definition of the call length repartition table (unit is ms) -->\n"
2868
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2873
/************* Default_scenario[8] ***************/
2875
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2876
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2878
"<!-- This program is free software; you can redistribute it and/or -->\n"
2879
"<!-- modify it under the terms of the GNU General Public License as -->\n"
2880
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2881
"<!-- License, or (at your option) any later version. -->\n"
2883
"<!-- This program is distributed in the hope that it will be useful, -->\n"
2884
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
2885
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
2886
"<!-- GNU General Public License for more details. -->\n"
2888
"<!-- You should have received a copy of the GNU General Public License -->\n"
2889
"<!-- along with this program; if not, write to the -->\n"
2890
"<!-- Free Software Foundation, Inc., -->\n"
2891
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
2893
"<!-- Sipp default 'branchs' scenario. -->\n"
2896
"<scenario name=\"branch_server\">\n"
2897
" <recv request=\"REGISTER\">\n"
2906
" [last_To:];tag=[pid]SIPpTag08[call_number]\n"
2907
" [last_Call-ID:]\n"
2909
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2910
" Content-Length: 0\n"
2916
" <!-- Set variable 3 if the ua is of the form ua2... -->\n"
2917
" <recv request=\"INVITE\" crlf=\"true\">\n"
2919
" <ereg regexp=\"ua2\"\n"
2920
" search_in=\"hdr\"\n"
2921
" header=\"From: \"\n"
2922
" assign_to=\"3\"/>\n"
2926
" <!-- send 180 then trying if variable 3 is set -->\n"
2927
" <send next=\"1\" test=\"3\">\n"
2930
" SIP/2.0 180 Ringing\n"
2933
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2934
" [last_Call-ID:]\n"
2936
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2937
" Content-Length: 0\n"
2942
" <!-- if not, send a 403 error then skip to wait for a BYE -->\n"
2943
" <send next=\"2\">\n"
2946
" SIP/2.0 403 Error\n"
2949
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2950
" [last_Call-ID:]\n"
2952
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2953
" Content-Length: 0\n"
2958
" <label id=\"1\"/>\n"
2963
" SIP/2.0 100 Trying\n"
2966
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2967
" [last_Call-ID:]\n"
2969
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2970
" Content-Length: 0\n"
2975
" <send retrans=\"500\">\n"
2981
" [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2982
" [last_Call-ID:]\n"
2984
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2985
" Content-Type: application/sdp\n"
2986
" Content-Length: [len]\n"
2989
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2991
" c=IN IP[media_ip_type] [media_ip]\n"
2993
" m=audio [media_port] RTP/AVP 0\n"
2994
" a=rtpmap:0 PCMU/8000\n"
2999
" <recv request=\"ACK\"\n"
3000
" optional=\"true\"\n"
3005
" <label id=\"2\"/>\n"
3007
" <recv request=\"BYE\">\n"
3017
" [last_Call-ID:]\n"
3019
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3020
" Content-Length: 0\n"
3025
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
3026
" <!-- able to retransmit it if we receive the BYE again. -->\n"
3027
" <timewait milliseconds=\"4000\"/>\n"
3029
" <!-- Definition of the response time repartition table (unit is ms) -->\n"
3030
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3032
" <!-- Definition of the call length repartition table (unit is ms) -->\n"
3033
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3038
/* Although this scenario will not work without pcap play enabled, there is no
3039
* harm in including it in the binary anyway, because the user could have
3040
* dumped it and passed it with -sf. */
3042
/************* Default_scenario[9] ***************/
3044
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3045
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3047
"<!-- This program is free software; you can redistribute it and/or -->\n"
3048
"<!-- modify it under the terms of the GNU General Public License as -->\n"
3049
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3050
"<!-- License, or (at your option) any later version. -->\n"
3052
"<!-- This program is distributed in the hope that it will be useful, -->\n"
3053
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
3054
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
3055
"<!-- GNU General Public License for more details. -->\n"
3057
"<!-- You should have received a copy of the GNU General Public License -->\n"
3058
"<!-- along with this program; if not, write to the -->\n"
3059
"<!-- Free Software Foundation, Inc., -->\n"
3060
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
3062
"<!-- Sipp 'uac' scenario with pcap (rtp) play -->\n"
3065
"<scenario name=\"UAC with media\">\n"
3066
" <!-- In client mode (sipp placing calls), the Call-ID MUST be -->\n"
3067
" <!-- generated by sipp. To do so, use [call_id] keyword. -->\n"
3068
" <send retrans=\"500\">\n"
3071
" INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3072
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3073
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3074
" To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
3075
" Call-ID: [call_id]\n"
3077
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3078
" Max-Forwards: 70\n"
3079
" Subject: Performance Test\n"
3080
" Content-Type: application/sdp\n"
3081
" Content-Length: [len]\n"
3084
" o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
3086
" c=IN IP[local_ip_type] [local_ip]\n"
3088
" m=audio [auto_media_port] RTP/AVP 8 101\n"
3089
" a=rtpmap:8 PCMA/8000\n"
3090
" a=rtpmap:101 telephone-event/8000\n"
3091
" a=fmtp:101 0-11,16\n"
3096
" <recv response=\"100\" optional=\"true\">\n"
3099
" <recv response=\"180\" optional=\"true\">\n"
3102
" <!-- By adding rrs=\"true\" (Record Route Sets), the route sets -->\n"
3103
" <!-- are saved and used for following messages sent. Useful to test -->\n"
3104
" <!-- against stateful SIP proxies/B2BUAs. -->\n"
3105
" <recv response=\"200\" rtd=\"true\" crlf=\"true\">\n"
3108
" <!-- Packet lost can be simulated in any send/recv message by -->\n"
3109
" <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent. -->\n"
3113
" ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3114
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3115
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3116
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3117
" Call-ID: [call_id]\n"
3119
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3120
" Max-Forwards: 70\n"
3121
" Subject: Performance Test\n"
3122
" Content-Length: 0\n"
3127
" <!-- Play a pre-recorded PCAP file (RTP stream) -->\n"
3130
" <exec play_pcap_audio=\"pcap/g711a.pcap\"/>\n"
3134
" <!-- Pause 8 seconds, which is approximately the duration of the -->\n"
3135
" <!-- PCAP file -->\n"
3136
" <pause milliseconds=\"8000\"/>\n"
3138
" <!-- Play an out of band DTMF '1' -->\n"
3141
" <exec play_pcap_audio=\"pcap/dtmf_2833_1.pcap\"/>\n"
3145
" <pause milliseconds=\"1000\"/>\n"
3147
" <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
3148
" <send retrans=\"500\">\n"
3151
" BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3152
" Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3153
" From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3154
" To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3155
" Call-ID: [call_id]\n"
3157
" Contact: sip:sipp@[local_ip]:[local_port]\n"
3158
" Max-Forwards: 70\n"
3159
" Subject: Performance Test\n"
3160
" Content-Length: 0\n"
3165
" <recv response=\"200\" crlf=\"true\">\n"
3168
" <!-- definition of the response time repartition table (unit is ms) -->\n"
3169
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3171
" <!-- definition of the call length repartition table (unit is ms) -->\n"
3172
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3176
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3177
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3179
"<!-- This program is free software; you can redistribute it and/or -->\n"
3180
"<!-- modify it under the terms of the GNU General Public License as -->\n"
3181
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3182
"<!-- License, or (at your option) any later version. -->\n"
3184
"<!-- This program is distributed in the hope that it will be useful, -->\n"
3185
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->\n"
3186
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->\n"
3187
"<!-- GNU General Public License for more details. -->\n"
3189
"<!-- You should have received a copy of the GNU General Public License -->\n"
3190
"<!-- along with this program; if not, write to the -->\n"
3191
"<!-- Free Software Foundation, Inc., -->\n"
3192
"<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->\n"
3194
"<!-- Sipp default 'uas' scenario. -->\n"
3197
"<scenario name=\"Out-of-call UAS\">\n"
3198
" <recv request=\".*\" regexp_match=\"true\" />\n"
3206
" [last_Call-ID:]\n"
3208
" Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3209
" Content-Length: 0\n"
3214
" <!-- Keep the call open for a while in case the 200 is lost to be -->\n"
3215
" <!-- able to retransmit it if we receive the BYE again. -->\n"
3216
" <timewait milliseconds=\"4000\"/>\n"
3219
" <!-- definition of the response time repartition table (unit is ms) -->\n"
3220
" <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3222
" <!-- definition of the call length repartition table (unit is ms) -->\n"
3223
" <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"