aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/bus/bus.h
blob: 69060d383ce9b1c263a4042ed47bada94f29e71d (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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
 * Copyright (C) 2006-2009 Martin Willi
 * 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.
 */

/**
 * @defgroup bus bus
 * @{ @ingroup libcharon
 */

#ifndef BUS_H_
#define BUS_H_

typedef enum alert_t alert_t;
typedef enum narrow_hook_t narrow_hook_t;
typedef struct bus_t bus_t;

#include <stdarg.h>

#include <debug.h>
#include <sa/ike_sa.h>
#include <sa/child_sa.h>
#include <processing/jobs/job.h>
#include <bus/listeners/listener.h>

/* undefine the definitions from libstrongswan */
#undef DBG0
#undef DBG1
#undef DBG2
#undef DBG3
#undef DBG4

#ifndef DEBUG_LEVEL
# define DEBUG_LEVEL 4
#endif /* DEBUG_LEVEL */

#if DEBUG_LEVEL >= 0
#define DBG0(group, format, ...) charon->bus->log(charon->bus, group, 0, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 0 */
#if DEBUG_LEVEL >= 1
#define DBG1(group, format, ...) charon->bus->log(charon->bus, group, 1, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 1 */
#if DEBUG_LEVEL >= 2
#define DBG2(group, format, ...) charon->bus->log(charon->bus, group, 2, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 2 */
#if DEBUG_LEVEL >= 3
#define DBG3(group, format, ...) charon->bus->log(charon->bus, group, 3, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 3 */
#if DEBUG_LEVEL >= 4
#define DBG4(group, format, ...) charon->bus->log(charon->bus, group, 4, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 4 */

#ifndef DBG0
# define DBG0(...) {}
#endif /* DBG0 */
#ifndef DBG1
# define DBG1(...) {}
#endif /* DBG1 */
#ifndef DBG2
# define DBG2(...) {}
#endif /* DBG2 */
#ifndef DBG3
# define DBG3(...) {}
#endif /* DBG3 */
#ifndef DBG4
# define DBG4(...) {}
#endif /* DBG4 */

/**
 * Kind of alerts to raise.
 */
enum alert_t {
	/** a RADIUS server did not respond, no additional arguments */
	ALERT_RADIUS_NOT_RESPONDING,
	/** a shutdown signal has been received, argument is the signal (int) */
	ALERT_SHUTDOWN_SIGNAL,
	/** peer authentication failed, no arguments */
	ALERT_PEER_AUTH_FAILED,
	/** failed to resolve peer address, no arguments */
	ALERT_PEER_ADDR_FAILED,
};

/**
 * Kind of narrow hook.
 *
 * There is a non-authenticated (IKE_AUTH) and a authenticated
 * (CREATE_CHILD_SA) narrowing hook for the initiator. Only one of these
 * hooks is invoked before the exchange.
 * To verify the traffic selectors negotiated, each PRE hook has a POST
 * counterpart that follows. POST hooks are invoked with an authenticated peer.
 * It is usually not a good idea to narrow in the POST hooks,
 * as the resulting traffic selector is not negotiated and results
 * in non-matching policies.
 */
enum narrow_hook_t {
	/** invoked as initiator before exchange, peer is not yet authenticated */
	NARROW_INITIATOR_PRE_NOAUTH,
	/** invoked as initiator before exchange, peer is authenticated */
	NARROW_INITIATOR_PRE_AUTH,
	/** invoked as responder during exchange, peer is authenticated */
	NARROW_RESPONDER,
	/** invoked as initiator after exchange, follows a INITIATOR_PRE_NOAUTH */
	NARROW_INITIATOR_POST_NOAUTH,
	/** invoked as initiator after exchange, follows a INITIATOR_PRE_AUTH */
	NARROW_INITIATOR_POST_AUTH,
};

/**
 * The bus receives events and sends them to all registered listeners.
 *
 * Any events sent to are delivered to all registered listeners. Threads
 * may wait actively to events using the blocking listen() call.
 */
struct bus_t {

	/**
	 * Register a listener to the bus.
	 *
	 * A registered listener receives all events which are sent to the bus.
	 * The listener is passive; the thread which emitted the event
	 * processes the listener routine.
	 *
	 * @param listener	listener to register.
	 */
	void (*add_listener) (bus_t *this, listener_t *listener);

	/**
	 * Unregister a listener from the bus.
	 *
	 * @param listener	listener to unregister.
	 */
	void (*remove_listener) (bus_t *this, listener_t *listener);

	/**
	 * Register a listener and block the calling thread.
	 *
	 * This call registers a listener and blocks the calling thread until
	 * its listeners function returns FALSE. This allows to wait for certain
	 * events. The associated job is executed after the listener has been
	 * registered: This allows to listen on events we initiate with the job,
	 * without missing any events to job may fire.
	 *
	 * @param listener	listener to register
	 * @param job		job to execute asynchronously when registered, or NULL
	 * @param timeout	max timeout in ms to listen for events, 0 to disable
	 * @return			TRUE if timed out
	 */
	bool (*listen)(bus_t *this, listener_t *listener, job_t *job, u_int timeout);

	/**
	 * Set the IKE_SA the calling thread is using.
	 *
	 * To associate an received log message to an IKE_SA without passing it as
	 * parameter each time, the thread registers the currenlty used IKE_SA
	 * during check-out. Before check-in, the thread unregisters the IKE_SA.
	 * This IKE_SA is stored per-thread, so each thread has its own IKE_SA
	 * registered.
	 *
	 * @param ike_sa	ike_sa to register, or NULL to unregister
	 */
	void (*set_sa) (bus_t *this, ike_sa_t *ike_sa);

	/**
	 * Get the IKE_SA the calling thread is currently using.
	 *
	 * If a thread currently does not know what IKE_SA it is processing,
	 * it can call get_sa() to look up the SA set during checkout via set_sa().
	 *
	 * @return			registered ike_sa, NULL if none registered
	 */
	ike_sa_t* (*get_sa)(bus_t *this);

	/**
	 * Send a log message to the bus.
	 *
	 * The signal specifies the type of the event occurred. The format string
	 * specifies an additional informational or error message with a
	 * printf() like variable argument list.
	 * Use the DBG() macros.
	 *
	 * @param group		debugging group
	 * @param level		verbosity level of the signal
	 * @param format	printf() style format string
	 * @param ...		printf() style argument list
	 */
	void (*log)(bus_t *this, debug_t group, level_t level, char* format, ...);

	/**
	 * Send a log message to the bus using va_list arguments.
	 *
	 * Same as bus_t.signal(), but uses va_list argument list.
	 *
	 * @param group		kind of the signal (up, down, rekeyed, ...)
	 * @param level		verbosity level of the signal
	 * @param format	printf() style format string
	 * @param args		va_list arguments
	 */
	void (*vlog)(bus_t *this, debug_t group, level_t level,
				 char* format, va_list args);

	/**
	 * Raise an alert over the bus.
	 *
	 * @param alert		kind of alert
	 * @param ...		alert specific attributes
	 */
	void (*alert)(bus_t *this, alert_t alert, ...);

	/**
	 * Send a IKE_SA state change event to the bus.
	 *
	 * @param ike_sa	IKE_SA which changes its state
	 * @param state		new state IKE_SA changes to
	 */
	void (*ike_state_change)(bus_t *this, ike_sa_t *ike_sa,
							 ike_sa_state_t state);
	/**
	 * Send a CHILD_SA state change event to the bus.
	 *
	 * @param child_sa	CHILD_SA which changes its state
	 * @param state		new state CHILD_SA changes to
	 */
	void (*child_state_change)(bus_t *this, child_sa_t *child_sa,
							   child_sa_state_t state);
	/**
	 * Message send/receive hook.
	 *
	 * @param message	message to send/receive
	 * @param incoming	TRUE for incoming messages, FALSE for outgoing
	 */
	void (*message)(bus_t *this, message_t *message, bool incoming);

	/**
	 * IKE_SA authorization hook.
	 *
	 * @param final		TRUE if this is the final invocation
	 * @return			TRUE to establish IKE_SA, FALSE to send AUTH_FAILED
	 */
	bool (*authorize)(bus_t *this, bool final);

	/**
	 * CHILD_SA traffic selector narrowing hook.
	 *
	 * @param child_sa	CHILD_SA set up with these traffic selectors
	 * @param type		type of hook getting invoked
	 * @param local		list of local traffic selectors to narrow
	 * @param remote	list of remote traffic selectors to narrow
	 */
	void (*narrow)(bus_t *this, child_sa_t *child_sa, narrow_hook_t type,
				   linked_list_t *local, linked_list_t *remote);

	/**
	 * IKE_SA keymat hook.
	 *
	 * @param ike_sa	IKE_SA this keymat belongs to
	 * @param dh		diffie hellman shared secret
	 * @param nonce_i	initiators nonce
	 * @param nonce_r	responders nonce
	 * @param rekey		IKE_SA we are rekeying, if any
	 */
	void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
					 chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey);
	/**
	 * CHILD_SA keymat hook.
	 *
	 * @param child_sa	CHILD_SA this keymat is used for
	 * @param initiator	initiator of the CREATE_CHILD_SA exchange
	 * @param dh		diffie hellman shared secret
	 * @param nonce_i	initiators nonce
	 * @param nonce_r	responders nonce
	 */
	void (*child_keys)(bus_t *this, child_sa_t *child_sa, bool initiator,
					   diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);

	/**
	 * IKE_SA up/down hook.
	 *
	 * @param ike_sa	IKE_SA coming up/going down
	 * @param up		TRUE for an up event, FALSE for a down event
	 */
	void (*ike_updown)(bus_t *this, ike_sa_t *ike_sa, bool up);

	/**
	 * IKE_SA rekeying hook.
	 *
	 * @param old		rekeyed and obsolete IKE_SA
	 * @param new		new IKE_SA replacing old
	 */
	void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new);

	/**
	 * CHILD_SA up/down hook.
	 *
	 * @param child_sa	CHILD_SA coming up/going down
	 * @param up		TRUE for an up event, FALSE for a down event
	 */
	void (*child_updown)(bus_t *this, child_sa_t *child_sa, bool up);

	/**
	 * CHILD_SA rekeying hook.
	 *
	 * @param old		rekeyed and obsolete CHILD_SA
	 * @param new		new CHILD_SA replacing old
	 */
	void (*child_rekey)(bus_t *this, child_sa_t *old, child_sa_t *new);

	/**
	 * Destroy the event bus.
	 */
	void (*destroy) (bus_t *this);
};

/**
 * Create the event bus which forwards events to its listeners.
 *
 * @return		event bus instance
 */
bus_t *bus_create();

#endif /** BUS_H_ @}*/