Avoid proxy for bypass_socket, enable_udp_decap
[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_AE,
26 "NONCE_CONTEXT",
27 "DH_CONTEXT",
28 "ISA_CONTEXT",
29 "AE_CONTEXT");
30 ENUM_END(tkm_context_kind_names, TKM_CTX_AE);
31
32 typedef struct private_tkm_id_manager_t private_tkm_id_manager_t;
33
34 /**
35 * private data of tkm_id_manager
36 */
37 struct private_tkm_id_manager_t {
38
39 /**
40 * public functions
41 */
42 tkm_id_manager_t public;
43
44 /**
45 * Per-kind array of free context ids
46 */
47 bool* ctxids[TKM_CTX_MAX];
48
49 /**
50 * Per-kind context limits.
51 */
52 tkm_limits_t limits;
53
54 /**
55 * rwlocks for context id lists
56 */
57 rwlock_t *locks[TKM_CTX_MAX];
58
59 };
60
61 /**
62 * Check if given kind is a valid context kind value.
63 *
64 * @param kind context kind to check
65 * @return TRUE if given kind is a valid context kind,
66 * FALSE otherwise
67 */
68 static bool is_valid_kind(const tkm_context_kind_t kind)
69 {
70 return (int)kind >= 0 && kind < TKM_CTX_MAX;
71 };
72
73 METHOD(tkm_id_manager_t, acquire_id, int,
74 private_tkm_id_manager_t * const this, const tkm_context_kind_t kind)
75 {
76 int id = 0;
77 uint64_t j;
78
79 if (!is_valid_kind(kind))
80 {
81 DBG1(DBG_LIB, "tried to acquire id for invalid context kind '%d'",
82 kind);
83 return 0;
84 }
85
86 this->locks[kind]->write_lock(this->locks[kind]);
87 for (j = 0; j < this->limits[kind]; j++)
88 {
89 if (!this->ctxids[kind][j])
90 {
91 this->ctxids[kind][j] = true;
92 id = j + 1;
93 break;
94 }
95 }
96 this->locks[kind]->unlock(this->locks[kind]);
97
98 if (!id)
99 {
100 DBG1(DBG_LIB, "acquiring %N context id failed",
101 tkm_context_kind_names, kind);
102 }
103
104 return id;
105 }
106
107 METHOD(tkm_id_manager_t, release_id, bool,
108 private_tkm_id_manager_t * const this, const tkm_context_kind_t kind,
109 const int id)
110 {
111 const int idx = id - 1;
112
113 if (!is_valid_kind(kind))
114 {
115 DBG1(DBG_LIB, "tried to release id %d for invalid context kind '%d'",
116 id, kind);
117 return FALSE;
118 }
119
120 this->locks[kind]->write_lock(this->locks[kind]);
121 this->ctxids[kind][idx] = false;
122 this->locks[kind]->unlock(this->locks[kind]);
123
124 return TRUE;
125 }
126
127
128 METHOD(tkm_id_manager_t, destroy, void,
129 private_tkm_id_manager_t *this)
130 {
131 int i;
132 for (i = 0; i < TKM_CTX_MAX; i++)
133 {
134 free(this->ctxids[i]);
135 this->locks[i]->destroy(this->locks[i]);
136 }
137 free(this);
138 }
139
140 /*
141 * see header file
142 */
143 tkm_id_manager_t *tkm_id_manager_create(const tkm_limits_t limits)
144 {
145 private_tkm_id_manager_t *this;
146 int i;
147
148 INIT(this,
149 .public = {
150 .acquire_id = _acquire_id,
151 .release_id = _release_id,
152 .destroy = _destroy,
153 },
154 );
155
156 for (i = 0; i < TKM_CTX_MAX; i++)
157 {
158 this->limits[i] = limits[i];
159 this->ctxids[i] = calloc(limits[i], sizeof(bool));
160 this->locks[i] = rwlock_create(RWLOCK_TYPE_DEFAULT);
161 DBG2(DBG_LIB, "%N initialized, %llu slot(s)",
162 tkm_context_kind_names, i, limits[i]);
163 }
164
165 return &this->public;
166 }