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