Various stylistic fixes
[strongswan.git] / src / charon-tkm / src / tkm / tkm_id_manager.c
1 /*
2 * Copyright (C) 2012 Reto Buerki
3 * Copyright (C) 2012 Adrian-Ken Rueegsegger
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "tkm_id_manager.h"
18
19 #include <utils/debug.h>
20 #include <collections/linked_list.h>
21 #include <threading/rwlock.h>
22
23 #define TKM_LIMIT 100
24
25 ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA,
26 "NONCE_CONTEXT",
27 "DH_CONTEXT",
28 "CC_CONTEXT"
29 "ISA_CONTEXT",
30 "AE_CONTEXT",
31 "ESA_CONTEXT");
32 ENUM_END(tkm_context_kind_names, TKM_CTX_ESA);
33
34 typedef struct private_tkm_id_manager_t private_tkm_id_manager_t;
35
36 /**
37 * private data of tkm_id_manager
38 */
39 struct private_tkm_id_manager_t {
40
41 /**
42 * public functions
43 */
44 tkm_id_manager_t public;
45
46 /**
47 * Per-kind array of free context ids
48 */
49 bool* ctxids[TKM_CTX_MAX];
50
51 /**
52 * Per-kind context limits.
53 */
54 tkm_limits_t limits;
55
56 /**
57 * rwlocks for context id lists
58 */
59 rwlock_t *locks[TKM_CTX_MAX];
60
61 };
62
63 /**
64 * Check if given kind is a valid context kind value.
65 *
66 * @param kind context kind to check
67 * @return TRUE if given kind is a valid context kind,
68 * FALSE otherwise
69 */
70 static bool is_valid_kind(const tkm_context_kind_t kind)
71 {
72 return (int)kind >= 0 && kind < TKM_CTX_MAX;
73 };
74
75 METHOD(tkm_id_manager_t, acquire_id, int,
76 private_tkm_id_manager_t * const this, const tkm_context_kind_t kind)
77 {
78 int id = 0;
79 uint64_t j;
80
81 if (!is_valid_kind(kind))
82 {
83 DBG1(DBG_LIB, "tried to acquire id for invalid context kind '%d'",
84 kind);
85 return 0;
86 }
87
88 this->locks[kind]->write_lock(this->locks[kind]);
89 for (j = 0; j < this->limits[kind]; j++)
90 {
91 if (!this->ctxids[kind][j])
92 {
93 this->ctxids[kind][j] = true;
94 id = j + 1;
95 break;
96 }
97 }
98 this->locks[kind]->unlock(this->locks[kind]);
99
100 if (!id)
101 {
102 DBG1(DBG_LIB, "acquiring %N context id failed", tkm_context_kind_names,
103 kind);
104 }
105
106 return id;
107 }
108
109 METHOD(tkm_id_manager_t, release_id, bool,
110 private_tkm_id_manager_t * const this, const tkm_context_kind_t kind,
111 const int id)
112 {
113 const int idx = id - 1;
114
115 if (!is_valid_kind(kind))
116 {
117 DBG1(DBG_LIB, "tried to release id %d for invalid context kind '%d'",
118 id, kind);
119 return FALSE;
120 }
121
122 this->locks[kind]->write_lock(this->locks[kind]);
123 this->ctxids[kind][idx] = false;
124 this->locks[kind]->unlock(this->locks[kind]);
125
126 return TRUE;
127 }
128
129
130 METHOD(tkm_id_manager_t, destroy, void,
131 private_tkm_id_manager_t *this)
132 {
133 int i;
134 for (i = 0; i < TKM_CTX_MAX; i++)
135 {
136 free(this->ctxids[i]);
137 this->locks[i]->destroy(this->locks[i]);
138 }
139 free(this);
140 }
141
142 /*
143 * see header file
144 */
145 tkm_id_manager_t *tkm_id_manager_create(const tkm_limits_t limits)
146 {
147 private_tkm_id_manager_t *this;
148 int i;
149
150 INIT(this,
151 .public = {
152 .acquire_id = _acquire_id,
153 .release_id = _release_id,
154 .destroy = _destroy,
155 },
156 );
157
158 for (i = 0; i < TKM_CTX_MAX; i++)
159 {
160 this->limits[i] = limits[i];
161 this->ctxids[i] = calloc(limits[i], sizeof(bool));
162 this->locks[i] = rwlock_create(RWLOCK_TYPE_DEFAULT);
163 DBG2(DBG_LIB, "%N initialized, %llu slot(s)", tkm_context_kind_names, i,
164 limits[i]);
165 }
166
167 return &this->public;
168 }