733665f4f41d6b596dac7b797c07d31fe38a84fb
[strongswan.git] / Source / charon / testcases / ike_sa_manager_test.c
1 /**
2 * @file ike_sa_manager_test.c
3 *
4 * @brief Tests to test the IKE_SA-Manager type ike_sa_manager_t
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <string.h>
24 #include <pthread.h>
25 #include <unistd.h>
26
27 #include "ike_sa_manager_test.h"
28
29 #include <types.h>
30 #include <sa/ike_sa_manager.h>
31
32
33 static struct ike_sa_manager_test_struct_s {
34 tester_t *tester;
35 ike_sa_manager_t *isam;
36 } td;
37
38 static void test1_thread(ike_sa_id_t *ike_sa_id)
39 {
40 ike_sa_t *ike_sa;
41 status_t status;
42
43 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
44 td.tester->assert_true(td.tester, (status == SUCCESS), "checkout of a blocked ike_sa");
45 usleep(10000);
46 status = td.isam->checkin(td.isam, ike_sa);
47 td.tester->assert_true(td.tester, (status == SUCCESS), "checkin of a requested ike_sa");
48 }
49
50
51 static void test2_thread(ike_sa_id_t *ike_sa_id)
52 {
53 ike_sa_t *ike_sa;
54 status_t status;
55
56 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
57 td.tester->assert_true(td.tester, (status == NOT_FOUND), "IKE_SA already deleted");
58 }
59
60 static void test3_thread(ike_sa_id_t *ike_sa_id)
61 {
62 ike_sa_t *ike_sa;
63 status_t status;
64
65 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
66 td.tester->assert_true(td.tester, (status == NOT_FOUND), "IKE_SA already deleted");
67
68 ike_sa_id->destroy(ike_sa_id);
69 }
70
71
72
73
74 void test_ike_sa_manager(tester_t *tester)
75 {
76 status_t status;
77 u_int64_t initiator, responder;
78 ike_sa_id_t *ike_sa_id, *sa_id;
79 ike_sa_t *ike_sa;
80 int thread_count = 200;
81 int sa_count = 100;
82 int i;
83 pthread_t threads[thread_count];
84
85 td.tester = tester;
86 td.isam = ike_sa_manager_create();
87 tester->assert_true(tester, (td.isam != NULL), "ike_sa_manager creation");
88
89
90
91
92 /* First Test:
93 * we play initiator for IKE_SA_INIT first
94 * create an IKE_SA,
95 *
96 */
97
98 td.isam->create_and_checkout(td.isam, &ike_sa);
99 /* for testing purposes, we manipulate the responder spi.
100 * this is usually done be the response from the communication partner,
101 * but we don't have one...
102 */
103 responder = 123;
104
105 sa_id = ike_sa->get_id(ike_sa);
106 sa_id->set_responder_spi(sa_id, responder);
107
108 status = sa_id->clone(sa_id,&ike_sa_id);
109 tester->assert_true(tester, (status == SUCCESS), "clone sa id");
110
111 /* check in, so we should have a "completed" sa, specified by ike_sa_id */
112 status = td.isam->checkin(td.isam, ike_sa);
113 tester->assert_true(tester, (status == SUCCESS), "checkin modified IKE_SA");
114
115 /* now we check it out and start some other threads */
116 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
117 tester->assert_true(tester, (status == SUCCESS), "checkout existing IKE_SA 1");
118
119 for (i = 0; i < thread_count; i++)
120 {
121 if (pthread_create(&threads[i], NULL, (void*(*)(void*))test1_thread, (void*)ike_sa_id))
122 {
123 /* failed, decrease list */
124 thread_count--;
125 i--;
126 }
127 }
128 sleep(1);
129
130
131 status = td.isam->checkin(td.isam, ike_sa);
132 tester->assert_true(tester, (status == SUCCESS), "checkin IKE_SA");
133
134
135 sleep(1);
136 /* we now delete the IKE_SA, while it is requested by the threads.
137 * this should block until the have done their work.*/
138 status = td.isam->delete(td.isam, ike_sa_id);
139 tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by id");
140
141
142 for (i = 0; i < thread_count; i++)
143 {
144 pthread_join(threads[i], NULL);
145 }
146
147 ike_sa_id->destroy(ike_sa_id);
148
149
150 /* Second Test:
151 * now we simulate our partner initiates an IKE_SA_INIT,
152 * so we are the responder.
153 *
154 */
155 memset(&initiator, 0, sizeof(initiator));
156 memset(&responder, 0, sizeof(responder));
157
158 initiator = 123;
159 ike_sa_id = ike_sa_id_create(initiator, responder, TRUE);
160
161 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
162 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 2");
163 for (i = 0; i < thread_count; i++)
164 {
165 if (pthread_create(&threads[i], NULL, (void*(*)(void*))test2_thread, (void*)ike_sa_id))
166 {
167 /* failed, decrease list */
168 thread_count--;
169 i--;
170 }
171 }
172 /* let them go acquiring */
173 sleep(1);
174
175 /* this time, we delete the ike_sa while its checked out */
176 td.isam->checkin_and_delete(td.isam, ike_sa);
177 tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by SA");
178
179 for (i = 0; i < thread_count; i++)
180 {
181 pthread_join(threads[i], NULL);
182 }
183
184 ike_sa_id->destroy(ike_sa_id);
185
186 /* Third Test:
187 * put in a lot of IKE_SAs, check it out, set a thread waiting
188 * and destroy the manager...
189 */
190
191 memset(&initiator, 0, sizeof(initiator));
192 memset(&responder, 0, sizeof(responder));
193
194 thread_count = sa_count;
195
196 for (i = 0; i < sa_count; i++)
197 {
198 initiator = i + 1;
199 ike_sa_id = ike_sa_id_create(initiator, responder, FALSE);
200
201 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
202 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 3");
203
204 if (pthread_create(&threads[i], NULL, (void*(*)(void*))test3_thread, (void*)ike_sa_id))
205 {
206 /* failed, decrease list */
207 thread_count--;
208 }
209 }
210
211 /* let them go acquiring */
212 sleep(1);
213
214 td.isam->destroy(td.isam);
215
216 for (i = 0; i < thread_count; i++)
217 {
218 pthread_join(threads[i], NULL);
219 }
220
221
222 }
223