1 /*
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.
6  *
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.
11  *
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
15  *
16  *  Author : Richard GAYRAUD - 04 Nov 2003
17  *           Olivier Jacques
18  *           From Hewlett Packard Company.
19  *           Peter Higginson
20  *           JPeG
21  *           Guillaume TEISSIER from FTR&D
22  */
23 
24 #ifndef __SCENARIO__
25 #define __SCENARIO__
26 
27 #include <map>
28 #include <sys/socket.h>
29 #include "actions.hpp"
30 #include "variables.hpp"
31 #include "message.hpp"
32 #include "stat.hpp"
33 
34 
35 #define MSG_TYPE_SENDCMD   0
36 #define MSG_TYPE_RECVCMD   1
37 
38 #define MSG_TYPE_SEND      2
39 #define MSG_TYPE_RECV      3
40 #define MSG_TYPE_PAUSE     4
41 #define MSG_TYPE_NOP       5
42 
43 #define MODE_CLIENT        0
44 #define MODE_SERVER        1
45 
46 #define MODE_3PCC_NONE                0
47 #define MODE_3PCC_CONTROLLER_A  2
48 #define MODE_3PCC_CONTROLLER_B  3
49 #define MODE_3PCC_A_PASSIVE     4
50 
51 /* 3pcc extended mode*/
52 #define MODE_MASTER             5
53 #define MODE_MASTER_PASSIVE     6
54 #define MODE_SLAVE              7
55 
56 #define OPTIONAL_TRUE      1
57 #define OPTIONAL_FALSE     0
58 #define OPTIONAL_GLOBAL    2
59 
60 class message
61 {
62 
63 public:
64     /* If this is a pause */
65     CSample        *pause_distribution;
66     int            pause_variable;
67     /* This string is used for the display screen. */
68     char           *pause_desc;
69     /* Is this a final pause, intended for catching retransmissions? */
70     bool           timewait;
71 
72     /* Number of sessions in a pause */
73     int            sessions;
74 
75     /* should collect route set? */
76     bool           bShouldRecordRoutes;
77 
78     /* should collect authentication info? */
79     bool           bShouldAuthenticate;
80 
81     /* If this is a send */
82     SendingMessage *send_scheme;
83     unsigned int   retrans_delay;
84     /* The receive/send timeout. */
85     unsigned int   timeout;
86 
87     /* 3pcc extended mode: if this is a sendCmd */
88     char         * peer_dest;
89 
90     /* 3pcc extended mode: if this is a recvCmd */
91     char         * peer_src;
92 
93     /* If this is a recv */
94     int            recv_response;
95     char         * recv_request;
96     int            optional;
97     bool           advance_state;
98     int            regexp_match;
99     regex_t      * regexp_compile;
100 
101     /* Anyway */
102     int            start_rtd;
103     int            stop_rtd;
104     bool           repeat_rtd;
105     int            counter;
106     double         lost;
107     int            crlf;
108     bool           hide;
109     char *         display_str;
110     int            next;
111     char *         nextLabel;
112     int            test;
113     int            condexec;
114     bool           condexec_inverse;
115     int            chance;/* 0=always, RAND_MAX+1=never (test rand() >= chance) */
116     int            on_timeout;
117     char *         onTimeoutLabel;
118 
119     /* Statistics */
120     unsigned long   nb_sent;
121     unsigned long   nb_recv;
122     unsigned long   nb_sent_retrans;
123     unsigned long   nb_recv_retrans;
124     unsigned long   nb_timeout;
125     unsigned long   nb_unexp;
126     unsigned long   nb_lost;
127 
128     CActions*       M_actions;
129 
130     int             M_type;
131 
132     SendingMessage *M_sendCmdData;
133     unsigned long   M_nbCmdSent;
134     unsigned long   M_nbCmdRecv;
135 
136     typedef enum {
137         ContentLengthNoPresent = 0,
138         ContentLengthValueZero,
139         ContentLengthValueNoZero
140     } ContentLengthFlag;
141 
142     ContentLengthFlag   content_length_flag ;
143 
144     char           *recv_response_for_cseq_method_list;
145     int            start_txn;
146     int            ack_txn;
147     int            response_txn;
148     int            index;
149     const char *   desc;
150 
151     message(int index, const char *desc);
152     ~message();
153 };
154 
155 typedef std::vector<message *> msgvec;
156 
157 struct txnControlInfo {
158     char *name;
159     bool isInvite;
160     int acks;
161     int started;
162     int responses;
163 };
164 typedef std::vector<txnControlInfo> txnvec;
165 
166 
167 class scenario
168 {
169 public:
170     scenario(char * filename, int deflt);
171     ~scenario();
172 
173     void runInit();
174 
175     msgvec messages;
176     msgvec initmessages;
177     char *name;
178     int duration;
179     txnvec transactions;
180     int unexpected_jump;
181     int retaddr;
182     int pausedaddr;
183 
184     void computeSippMode();
185 
186     int get_var(const char *varName, const char *what);
187     int get_counter(const char *varName, const char *what);
188     int get_rtd(const char *ptr, bool start);
189     int find_var(const char *varName);
190 
191     CStat *stats;
192     AllocVariableTable *allocVars;
193 
194 private:
195 
196     /* The mapping of labels to IDs. */
197     str_int_map labelMap;
198     str_int_map initLabelMap;
199 
200     str_int_map txnMap;
201 
202     bool found_timewait;
203 
204     void getBookKeeping(message *message);
205     void getCommonAttributes(message *message);
206     void getActionForThisMessage(message *message);
207     void parseAction(CActions *actions);
208     void handle_arithmetic(CAction *tmpAction, const char *what);
209     void handle_rhs(CAction *tmpAction, const char *what);
210     void checkOptionalRecv(char *elem, unsigned int scenario_file_cursor);
211 
212     void apply_labels(msgvec v, str_int_map labels);
213     void validate_variable_usage();
214     void validate_txn_usage();
215 
216     int get_txn(const char *txnName, const char *what, bool start, bool isInvite, bool isAck);
217     int xp_get_var(const char *name, const char *what);
218     int xp_get_var(const char *name, const char *what, int defval);
219 
220     bool hidedefault;
221     bool last_recv_optional;
222 };
223 
224 /* There are external variable containing the current scenario */
225 extern scenario      *main_scenario;
226 extern scenario      *ooc_scenario;
227 extern scenario      *aa_scenario;
228 extern scenario      *display_scenario;
229 extern int           creationMode;
230 extern int           sendMode;
231 extern int           thirdPartyMode;
232 
233 extern message::ContentLengthFlag  content_length_flag;
234 
235 void load_scenario(char * filename,
236                    int    deflt);
237 
238 /* 3pcc extended mode */
239 void parse_slave_cfg();
240 
241 void getActionForThisMessage();
242 CSample *parse_distribution(bool oldstyle);
243 int  createIntegerTable(char          * P_listeStr,
244                         unsigned int ** listeInteger,
245                         int           * sizeOfList);
246 
247 int  isWellFormed(char * P_listeStr,
248                   int  * nombre);
249 
250 /* String table functions. */
251 int createStringTable(char * inputString, char *** stringList, int *sizeOfList);
252 void freeStringTable(char ** stringList, int sizeOfList);
253 
254 
255 
256 int find_scenario(const char *scenario);
257 extern const char * default_scenario[12];
258 
259 /* Useful utility functions for parsing integers, etc. */
260 long get_long(const char *ptr, const char *what);
261 unsigned long long get_long_long(const char *ptr, const char *what);
262 long get_time(const char *ptr, const char *what, int multiplier);
263 double get_double(const char *ptr, const char *what);
264 bool get_bool(const char *ptr, const char *what);
265 int time_string(double ms, char *res, int reslen);
266 int get_var(const char *varName, const char *what);
267 
268 extern int get_cr_number(const char *msg);
269 
270 #endif
271