openafs-void-star-pointers-20071031
[openafs.git] / src / rxkad / test / stress.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* RX Authentication Stress test: server side code. */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15 RCSID
16     ("$Header$");
17
18 #include <afs/stds.h>
19 #include <sys/types.h>
20 #ifdef AFS_NT40_ENV
21 #include <winsock2.h>
22 #else
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #endif
26 #include <stdio.h>
27 #include <lwp.h>
28 #include <rx/xdr.h>
29 #include <rx/rx.h>
30 #include <afs/com_err.h>
31 #include <afs/cmd.h>
32
33 #include <rx/rxkad.h>
34 #include "stress.h"
35 #include "stress_internal.h"
36 #include "rx/rx_globals.h"
37 #ifdef AFS_PTHREAD_ENV
38 #include <pthread.h>
39 #endif
40
41 int maxSkew = 5;
42
43
44 static char *whoami;
45
46 static int
47 StringToAuth(authname)
48      IN char *authname;
49 {
50     int nonoauth = 0;
51     if (strcmp(authname, "rxkad") == 0)
52         return rxkad_clear;
53     if (strcmp(authname, "rxkad_")) {
54         if (strncmp(authname, "rxkad_", 6) == 0)
55             nonoauth++, authname += 6;
56         if (strcmp(authname, "clear") == 0)
57             return rxkad_clear;
58         if (strcmp(authname, "auth") == 0)
59             return rxkad_auth;
60         if (strcmp(authname, "crypt") == 0)
61             return rxkad_crypt;
62         if (strcmp(authname, "null") == 0)
63             return -1;
64         if (strcmp(authname, "none") == 0)
65             return -1;
66         if (strncmp(authname, "noauth", 6) == 0)
67             return -1;
68         if (strncmp(authname, "unauth", 6) == 0)
69             return -1;
70         /* error */
71     }
72     fprintf(stderr,
73             "Unknown authentication name %s, using rxkad_clear by default\n",
74             authname);
75     return rxkad_clear;
76 }
77
78 #define aSERVER         0
79 #define aCLIENT         1
80 #define aSENDLEN        2
81 #define aRECVLEN        3
82 #define aFASTCALLS      4
83 #define aSLOWCALLS      5
84 #define aCOPIOUSCALLS   6
85 #define aPRINTSTATS     7
86 #define aPRINTTIMING    8
87 #define aNOEXIT         9
88 #define aSTHREADS      10
89 #define aCTHREADS      11
90 #define aCALLTEST      12
91 #define aHIJACKTEST    13
92 #define aAUTHENTICATION 14
93 #define aMINSERVERAUTH 15
94 #define aREPEATINTERVAL 16
95 #define aREPEATCOUNT   17
96 #define aSTOPSERVER    18
97 #define aTRACE         19
98 #define aMELT1b    20
99 #define aRECLAIM     21
100 #define a2DCHOICE     22
101 #define aMAXSKEW        23
102 #define aUSETOKENS 24
103 #define aCELL 25
104 #define aKEYFILE 26
105
106 static int
107 CommandProc(struct cmd_syndesc *as, void *arock)
108 {
109     long code;
110     int startServer = (as->parms[aSERVER].items != 0);
111     int startClient = (as->parms[aCLIENT].items != 0);
112 #ifndef AFS_PTHREAD_ENV
113     PROCESS pid;
114 #endif
115     struct serverParms *sParms;
116     struct clientParms *cParms;
117
118     sParms = (struct serverParms *)osi_Alloc(sizeof(*sParms));
119     cParms = (struct clientParms *)osi_Alloc(sizeof(*cParms));
120     memset(sParms, 0, sizeof(*sParms));
121     memset(cParms, 0, sizeof(*cParms));
122     sParms->whoami = cParms->whoami = whoami;
123
124     if (!(startServer || startClient)) {
125         /* Default to "-server -client <localhost>" */
126         gethostname(cParms->server, sizeof(cParms->server));
127         startServer = startClient = 1;
128     }
129
130     /* get booleans */
131     cParms->printStats = (as->parms[aPRINTSTATS].items != 0);
132     cParms->printTiming = (as->parms[aPRINTTIMING].items != 0);
133     cParms->noExit = (as->parms[aNOEXIT].items != 0);
134     cParms->callTest = (as->parms[aCALLTEST].items != 0);
135     cParms->hijackTest = (as->parms[aHIJACKTEST].items != 0);
136     cParms->stopServer = (as->parms[aSTOPSERVER].items != 0);
137     cParms->useTokens = (as->parms[aUSETOKENS].items != 0);
138
139     if (as->parms[aMELT1b].items)
140         meltdown_1pkt = 0;
141     if (as->parms[aRECLAIM].items)
142         rxi_doreclaim = 0;
143     if (as->parms[a2DCHOICE].items)
144         rxi_2dchoice = 0;
145
146     if (startServer) {
147         if (as->parms[aTRACE].items) {
148             extern char rxi_tracename[];
149             strcpy(rxi_tracename, as->parms[aTRACE].items->data);
150         }
151
152         /* These options not compatible with -server */
153         if (cParms->stopServer) {
154             code = RXKST_BADARGS;
155             afs_com_err(whoami, code, "stop server not compatible with -client");
156             return code;
157         }
158
159         /* process -server options */
160         sParms->threads = 3;    /* one less than channels/conn */
161         if (as->parms[aSTHREADS].items)
162             sParms->threads = atoi(as->parms[aSTHREADS].items->data);
163         sParms->authentication = 0;
164         if (as->parms[aMINSERVERAUTH].items)
165             sParms->authentication =
166                 StringToAuth(as->parms[aMINSERVERAUTH].items->data);
167         if (as->parms[aKEYFILE].items)
168             sParms->keyfile = as->parms[aKEYFILE].items->data;
169
170 #ifdef AFS_PTHREAD_ENV
171         {
172             pthread_t serverID;
173             pthread_attr_t tattr;
174
175             code = pthread_attr_init(&tattr);
176             if (code) {
177                 afs_com_err(whoami, code,
178                         "can't pthread_attr_init server process");
179                 return code;
180             }
181
182             code =
183                 pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
184             if (code) {
185                 afs_com_err(whoami, code,
186                         "can't pthread_attr_setdetachstate server process");
187                 return code;
188             }
189
190             code =
191                 pthread_create(&serverID, &tattr, rxkst_StartServer,
192                                (void *)sParms);
193         }
194 #else
195         code =
196             LWP_CreateProcess(rxkst_StartServer, 16000, LWP_NORMAL_PRIORITY,
197                               (opaque) sParms, "Server Process", &pid);
198 #endif
199         if (code) {
200             afs_com_err(whoami, code, "can't create server process");
201             return code;
202         }
203     } else {
204         /* check for server-only args */
205     }
206
207     if (startClient) {
208         u_long calls;           /* default number of calls */
209
210         /* process -client options */
211         if (as->parms[aCLIENT].items)
212             lcstring(cParms->server, as->parms[aCLIENT].items->data,
213                      sizeof(cParms->server));
214         cParms->threads = 6;    /* 150% of channels/conn */
215         if (as->parms[aCTHREADS].items)
216             cParms->threads = atoi(as->parms[aCTHREADS].items->data);
217         if (cParms->callTest || cParms->hijackTest || cParms->printTiming
218             || cParms->stopServer)
219             calls = 0;
220         else
221             calls = 1;
222         cParms->fastCalls = cParms->slowCalls = cParms->copiousCalls = calls;
223
224         cParms->sendLen = cParms->recvLen = 10000;
225         if (as->parms[aSENDLEN].items)
226             cParms->sendLen = atoi(as->parms[aSENDLEN].items->data);
227         if (as->parms[aRECVLEN].items)
228             cParms->recvLen = atoi(as->parms[aRECVLEN].items->data);
229         if (as->parms[aFASTCALLS].items)
230             cParms->fastCalls = atoi(as->parms[aFASTCALLS].items->data);
231         if (as->parms[aSLOWCALLS].items)
232             cParms->slowCalls = atoi(as->parms[aSLOWCALLS].items->data);
233         if (as->parms[aCOPIOUSCALLS].items)
234             cParms->copiousCalls = atoi(as->parms[aCOPIOUSCALLS].items->data);
235         cParms->repeatInterval = cParms->repeatCount = 0;
236         if (as->parms[aREPEATINTERVAL].items)
237             cParms->repeatInterval =
238                 atoi(as->parms[aREPEATINTERVAL].items->data);
239         if (as->parms[aREPEATCOUNT].items)
240             cParms->repeatCount = atoi(as->parms[aREPEATCOUNT].items->data);
241         if (as->parms[aMAXSKEW].items) {
242             maxSkew = atoi(as->parms[aMAXSKEW].items->data);
243             if (maxSkew < 1) {
244                 printf("Minimum allowed maxSkew is 1, resetting.\n");
245                 maxSkew = 1;
246             }
247         }
248
249         cParms->authentication = 0;
250         if (as->parms[aAUTHENTICATION].items)
251             cParms->authentication =
252                 StringToAuth(as->parms[aAUTHENTICATION].items->data);
253         cParms->cell = RXKST_CLIENT_CELL;
254         if (as->parms[aCELL].items)
255             cParms->cell = as->parms[aCELL].items->data;
256
257         code = rxkst_StartClient(cParms);
258         if (code) {
259             afs_com_err(whoami, code, "StartClient returned");
260             return code;
261         }
262     } else {
263         if (as->parms[aSENDLEN].items || as->parms[aRECVLEN].items
264             || as->parms[aFASTCALLS].items || as->parms[aSLOWCALLS].items
265             || as->parms[aCOPIOUSCALLS].items) {
266             code = RXKST_BADARGS;
267             afs_com_err(whoami, code,
268                     "send/recv len and # calls are client options");
269             return code;
270         }
271
272         /* donate this LWP to server-side */
273         rx_ServerProc();
274     }
275
276     return 0;
277 }
278
279 void
280 main(argc, argv)
281      IN int argc;
282      IN char *argv[];
283 {
284     long code;
285 #ifndef AFS_PTHREAD_ENV
286     PROCESS initialProcess;
287 #endif
288     struct cmd_syndesc *ts;
289
290     whoami = argv[0];
291
292     initialize_RXK_error_table();
293     initialize_RKS_error_table();
294     initialize_CMD_error_table();
295     initialize_KTC_error_table();
296
297     code = rx_Init(0);
298     rx_SetRxDeadTime(120);
299     if (code < 0) {
300         afs_com_err(whoami, code, "can't init Rx");
301         exit(1);
302     }
303 #ifndef AFS_PTHREAD_ENV
304     initialProcess = 0;
305     code = LWP_CurrentProcess(&initialProcess);
306     if (code) {
307         afs_com_err(whoami, code, "LWP initialization failed");
308         exit(1);
309     }
310 #endif
311     ts = cmd_CreateSyntax(NULL, CommandProc, NULL,
312                           "run Rx authentication stress test");
313     cmd_AddParm(ts, "-server", CMD_FLAG, CMD_OPTIONAL, "start server");
314     cmd_AddParm(ts, "-client", CMD_SINGLE, CMD_OPTIONAL, "start client");
315     cmd_AddParm(ts, "-sendlen", CMD_SINGLE, CMD_OPTIONAL,
316                 "bytes to send to server in Copious call");
317     cmd_AddParm(ts, "-recvlen", CMD_SINGLE, CMD_OPTIONAL,
318                 "bytes to request from server in Copious call");
319     cmd_AddParm(ts, "-fastcalls", CMD_SINGLE, CMD_OPTIONAL,
320                 "number of fast calls to make");
321     cmd_AddParm(ts, "-slowcalls", CMD_SINGLE, CMD_OPTIONAL,
322                 "number of slow calls to make (one second)");
323     cmd_AddParm(ts, "-copiouscalls", CMD_SINGLE, CMD_OPTIONAL,
324                 "number of fast calls to make");
325     cmd_AddParm(ts, "-printstatistics", CMD_FLAG, CMD_OPTIONAL,
326                 "print statistics before exiting");
327     cmd_AddParm(ts, "-printtimings", CMD_FLAG, CMD_OPTIONAL,
328                 "print timing information for calls");
329     cmd_AddParm(ts, "-noexit", CMD_FLAG, CMD_OPTIONAL,
330                 "don't exit after successful finish");
331     cmd_AddParm(ts, "-sthreads", CMD_SINGLE, CMD_OPTIONAL,
332                 "number server threads");
333     cmd_AddParm(ts, "-cthreads", CMD_SINGLE, CMD_OPTIONAL,
334                 "number client threads");
335     cmd_AddParm(ts, "-calltest", CMD_FLAG, CMD_OPTIONAL,
336                 "check server's call number verification (this takes about 30 seconds)");
337     cmd_AddParm(ts, "-hijacktest", CMD_FLAG, CMD_OPTIONAL,
338                 "check hijack prevention measures by making various modifications to incoming/outgoing packets");
339     cmd_AddParm(ts, "-authentication", CMD_SINGLE, CMD_OPTIONAL,
340                 "type of authentication to use; one of: none, clear, auth, crypt");
341     cmd_AddParm(ts, "-minserverauth", CMD_SINGLE, CMD_OPTIONAL,
342                 "minimum level of authentication permitted by server");
343     cmd_AddParm(ts, "-repeatinterval", CMD_SINGLE, CMD_OPTIONAL,
344                 "seconds between load test activity");
345     cmd_AddParm(ts, "-repeatcount", CMD_SINGLE, CMD_OPTIONAL,
346                 "repetitions of load test activity");
347     cmd_AddParm(ts, "-stopserver", CMD_FLAG, CMD_OPTIONAL,
348                 "send RPC to cause server to exit");
349     cmd_AddParm(ts, "-trace", CMD_SINGLE, CMD_OPTIONAL,
350                 "file for per-call trace info");
351     cmd_AddParm(ts, "-nomd1pkt", CMD_FLAG, CMD_OPTIONAL,
352                 "dont prefer one-packet calls");
353     cmd_AddParm(ts, "-noreclaim", CMD_FLAG, CMD_OPTIONAL,
354                 "dont aggressively reclaim packets");
355     cmd_AddParm(ts, "-no2dchoice", CMD_FLAG, CMD_OPTIONAL,
356                 "disable rx_getcall 2d choice code");
357     cmd_AddParm(ts, "-maxskew", CMD_SINGLE, CMD_OPTIONAL,
358                 "max client server skew in seconds");
359     cmd_AddParm(ts, "-usetokens", CMD_FLAG, CMD_OPTIONAL, "use ktc tokens");
360     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "name of test cell");
361     cmd_AddParm(ts, "-keyfile", CMD_SINGLE, CMD_OPTIONAL,
362                 "read server key from file");
363
364     code = cmd_Dispatch(argc, argv);
365     exit(code != 0);
366 }