1981378507aaf14bf3e3e065c9d2be284b1d3b18
[strongswan.git] / Source / charon / tests / 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 #include "../types.h"
29 #include "../tester.h"
30 #include "../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 successful_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 static void failed_thread(ike_sa_id_t *ike_sa_id)
51 {
52 ike_sa_t *ike_sa;
53 status_t status;
54
55 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
56 td.tester->assert_true(td.tester, (status == NOT_FOUND), "IKE_SA already deleted");
57 }
58
59 void test_ike_sa_manager(tester_t *tester)
60 {
61 status_t status;
62 spi_t initiator, responder;
63 ike_sa_id_t *ike_sa_id;
64 ike_sa_t *ike_sa;
65 int thread_count = 200;
66 int sa_count = 50;
67 int i;
68 pthread_t threads[thread_count];
69
70 td.tester = tester;
71 td.isam = ike_sa_manager_create();
72 tester->assert_true(tester, (td.isam != NULL), "ike_sa_manager creation");
73
74
75
76
77
78 /* First Test:
79 * we play initiator for IKE_SA_INIT first
80 * create an IKE_SA,
81 *
82 */
83 memset(&initiator, 0, sizeof(initiator));
84 memset(&responder, 0, sizeof(responder));
85
86 ike_sa_id = ike_sa_id_create(initiator, responder, INITIATOR);
87
88 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
89 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA");
90 /* for testing purposes, we manipulate the responder spi.
91 * this is usually done be the response from the communication partner,
92 * but we don't have one...
93 */
94 ike_sa_id->destroy(ike_sa_id);
95 ike_sa_id = ike_sa->get_id(ike_sa);
96 responder.low = 123;
97 ike_sa_id->set_responder_spi(ike_sa_id, responder);
98 /* check in, so we should have a "completed" sa, specified by ike_sa_id */
99 status = td.isam->checkin(td.isam, ike_sa);
100 tester->assert_true(tester, (status == SUCCESS), "checkin modified IKE_SA");
101
102 /* now we check it out and start some other threads */
103 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
104 tester->assert_true(tester, (status == SUCCESS), "checkout existing IKE_SA 1");
105
106
107
108 for (i = 0; i < thread_count; i++)
109 {
110 if (pthread_create(&threads[i], NULL, (void*(*)(void*))successful_thread, (void*)ike_sa_id))
111 {
112 /* failed, decrease list */
113 thread_count--;
114 i--;
115 }
116 }
117 sleep(1);
118
119
120 status = td.isam->checkin(td.isam, ike_sa);
121 tester->assert_true(tester, (status == SUCCESS), "checkin IKE_SA");
122
123
124 sleep(1);
125 /* we now delete the IKE_SA, while it is requested by the threads.
126 * this should block until the have done their work.*/
127 status = td.isam->delete(td.isam, ike_sa_id);
128 tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by id");
129
130
131 for (i = 0; i < thread_count; i++)
132 {
133 pthread_join(threads[i], NULL);
134 }
135
136 //ike_sa_id->destroy(ike_sa_id);
137
138
139
140
141
142 /* Second Test:
143 * now we simulate our partner initiates an IKE_SA_INIT,
144 * so we are the responder.
145 *
146 */
147
148 memset(&initiator, 0, sizeof(initiator));
149 memset(&responder, 0, sizeof(responder));
150
151 initiator.low = 123;
152 ike_sa_id = ike_sa_id_create(initiator, responder, RESPONDER);
153
154 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
155 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 2");
156 for (i = 0; i < thread_count; i++)
157 {
158 if (pthread_create(&threads[i], NULL, (void*(*)(void*))failed_thread, (void*)ike_sa_id))
159 {
160 /* failed, decrease list */
161 thread_count--;
162 i--;
163 }
164 }
165 /* let them go acquiring */
166 sleep(1);
167
168 /* this time, we delete the ike_sa while its checked out */
169 td.isam->checkin_and_delete(td.isam, ike_sa);
170 tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by SA");
171
172 for (i = 0; i < thread_count; i++)
173 {
174 pthread_join(threads[i], NULL);
175 }
176
177 //ike_sa_id->destroy(ike_sa_id);
178
179 /* Third Test:
180 * put in a lot of IKE_SAs, check it out, set a thread waiting
181 * and destroy the manager...
182 */
183
184 memset(&initiator, 0, sizeof(initiator));
185 memset(&responder, 0, sizeof(responder));
186
187 thread_count = sa_count;
188
189 for (i = 0; i < sa_count; i++)
190 {
191 initiator.low = i + 1;
192 ike_sa_id = ike_sa_id_create(initiator, responder, RESPONDER);
193
194 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
195 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 3");
196
197 if (pthread_create(&threads[i], NULL, (void*(*)(void*))failed_thread, (void*)ike_sa_id))
198 {
199 /* failed, decrease list */
200 thread_count--;
201 }
202 //ike_sa_id->destroy(ike_sa_id);
203 }
204
205 /* let them go acquiring */
206 sleep(1);
207
208 status = td.isam->destroy(td.isam);
209 tester->assert_true(tester, (status == SUCCESS), "ike_sa_manager destruction");
210
211 for (i = 0; i < thread_count; i++)
212 {
213 pthread_join(threads[i], NULL);
214 }
215
216 }
217