aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/sa/ike_sa_manager.h
blob: d10901ec53ca920e69517fad2aba6765bc027b25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
 * Copyright (C) 2008 Tobias Brunner
 * Copyright (C) 2005-2008 Martin Willi
 * Copyright (C) 2005 Jan Hutter
 * Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * $Id$
 */

/**
 * @defgroup ike_sa_manager ike_sa_manager
 * @{ @ingroup sa
 */

#ifndef IKE_SA_MANAGER_H_
#define IKE_SA_MANAGER_H_

typedef struct ike_sa_manager_t ike_sa_manager_t;

#include <library.h>
#include <sa/ike_sa.h>
#include <encoding/message.h>
#include <config/peer_cfg.h>

/**
 * Manages and synchronizes access to all IKE_SAs.
 *
 * To synchronize access to thread-unsave IKE_SAs, they are checked out for
 * use and checked in afterwards. A checked out SA is exclusively accessible
 * by the owning thread.
 */
struct ike_sa_manager_t {
	
	/**
	 * Checkout an existing IKE_SA.
	 * 
	 * @param ike_sa_id			the SA identifier, will be updated
	 * @returns 					
	 * 							- checked out IKE_SA if found
	 * 							- NULL, if specified IKE_SA is not found.
	 */
	ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id);
	
	/**
	 * Create and check out a new IKE_SA.
	 *
	 * @param initiator			TRUE for initiator, FALSE otherwise
	 * @returns 				created and checked out IKE_SA
	 */
	ike_sa_t* (*checkout_new) (ike_sa_manager_t* this, bool initiator);
	
	/**
	 * Checkout an IKE_SA by a message.
	 * 
	 * In some situations, it is necessary that the manager knows the
	 * message to use for the checkout. This has the following reasons:
	 * 
	 * 1. If the targeted IKE_SA is already processing a message, we do not
	 *    check it out if the message ID is the same.
	 * 2. If it is an IKE_SA_INIT request, we have to check if it is a 
	 *    retransmission. If so, we have to drop the message, we would
	 *    create another unneeded IKE_SA for each retransmitted packet.
	 *
	 * A call to checkout_by_message() returns a (maybe new created) IKE_SA.
	 * If processing the message does not make sense (for the reasons above),
	 * NULL is returned.
	 * 
	 * @param ike_sa_id			the SA identifier, will be updated
	 * @returns 					
	 * 							- checked out/created IKE_SA
	 * 							- NULL to not process message further
	 */
	ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message);
	
	/**
	 * Checkout an IKE_SA for initiation by a peer_config.
	 *
	 * To initiate, a CHILD_SA may be established within an existing IKE_SA.
	 * This call checks for an existing IKE_SA by comparing the configuration.
	 * If the CHILD_SA can be created in an existing IKE_SA, the matching SA
	 * is returned.
	 * If no IKE_SA is found, a new one is created. This is also the case when
	 * the found IKE_SA is in the DELETING state.
	 *
	 * @param peer_cfg			configuration used to find an existing IKE_SA
	 * @return					checked out/created IKE_SA
	 */
	ike_sa_t* (*checkout_by_config) (ike_sa_manager_t* this,
								 	 peer_cfg_t *peer_cfg);
	
	/**
	 * Check for duplicates of the given IKE_SA.
	 * 
	 * Measures are taken according to the uniqueness policy of the IKE_SA.
	 * The return value indicates whether duplicates have been found and if
	 * further measures should be taken (e.g. cancelling an IKE_AUTH exchange).
	 * check_uniqueness() must be called before the IKE_SA is complete,
	 * deadlocks occur otherwise.
	 * 
	 * @param ike_sa			ike_sa to check
	 * @return					TRUE, if the given IKE_SA has duplicates and
	 * 							should be deleted
	 */
	bool (*check_uniqueness)(ike_sa_manager_t *this, ike_sa_t *ike_sa);
	
	/**
	 * Check out an IKE_SA a unique ID.
	 *
	 * Every IKE_SA and every CHILD_SA is uniquely identified by an ID. 
	 * These checkout function uses, depending
	 * on the child parameter, the unique ID of the IKE_SA or the reqid
	 * of one of a IKE_SAs CHILD_SA.
	 *
	 * @param id				unique ID of the object
	 * @param child				TRUE to use CHILD, FALSE to use IKE_SA
	 * @return
	 * 							- checked out IKE_SA, if found
	 * 							- NULL, if not found
	 */
	ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id,
								 bool child);
	
	/**
	 * Check out an IKE_SA by the policy/connection name.
	 *
	 * Check out the IKE_SA by the configuration name, either from the IKE- or
	 * one of its CHILD_SAs.
	 *
	 * @param name				name of the connection/policy
	 * @param child				TRUE to use policy name, FALSE to use conn name
	 * @return
	 * 							- checked out IKE_SA, if found
	 * 							- NULL, if not found
	 */
	ike_sa_t* (*checkout_by_name) (ike_sa_manager_t* this, char *name,
								   bool child);
	
	/**
	 * Create an enumerator over all stored IKE_SAs.
	 *
	 * While enumerating an IKE_SA, it is temporarily checked out and
	 * automatically checked in after the current enumeration step.
	 *
	 * @return					enumerator over all IKE_SAs.
	 */
	enumerator_t *(*create_enumerator) (ike_sa_manager_t* this);
	
	/**
	 * Checkin the SA after usage.
	 *
	 * If the IKE_SA is not registered in the manager, a new entry is created.
	 *
	 * @param ike_sa_id			the SA identifier, will be updated
	 * @param ike_sa			checked out SA
	 */
	void (*checkin) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
	
	/**
	 * Destroy a checked out SA.
	 *
	 * The IKE SA is destroyed without notification of the remote peer.
	 * Use this only if the other peer doesn't respond or behaves not
	 * as predicted.
	 * Checking in and destruction is an atomic operation (for the IKE_SA),
	 * so this can be called if the SA is in a "unclean" state, without the
	 * risk that another thread can get the SA.
	 *
	 * @param ike_sa			SA to delete
	 */
	void (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
	
	/**
	 * Get the number of IKE_SAs which are in the connecting state.
	 *
	 * To prevent the server from resource exhaustion, cookies and other
	 * mechanisms are used. The number of half open IKE_SAs is a good
	 * indicator to see if a peer is flooding the server.
	 * If a host is supplied, only the number of half open IKE_SAs initiated
	 * from this IP are counted.
	 * Only SAs for which we are the responder are counted.
	 * 
	 * @param ip				NULL for all, IP for half open IKE_SAs with IP
	 * @return					number of half open IKE_SAs
	 */
	int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip);
	
	/**
	 * Delete all existing IKE_SAs and destroy them immediately.
	 * 
	 * Threads will be driven out, so all SAs can be deleted cleanly.
	 */
	void (*flush)(ike_sa_manager_t *this);
	
	/**
	 * Destroys the manager with all associated SAs.
	 *
	 * A call to flush() is required before calling destroy.
	 */
	void (*destroy) (ike_sa_manager_t *this);
};

/**
 * Create the IKE_SA manager.
 * 
 * @returns 	ike_sa_manager_t object, NULL if initialization fails
 */
ike_sa_manager_t *ike_sa_manager_create(void);

#endif /*IKE_SA_MANAGER_H_ @} */