2 * Copyright (C) 2011-2016 Tobias Brunner
3 * Copyright (C) 2006 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
21 #include <threading/thread.h>
22 #include <threading/thread_value.h>
23 #include <threading/mutex.h>
24 #include <threading/rwlock.h>
27 * These operations allow us to speed up the log level checks on some platforms.
28 * In particular if acquiring the read lock is expensive even in the absence of
31 * Note that while holding the read/write lock the read does not have to be
32 * atomic as the write lock must be held to set the level.
34 #ifdef HAVE_GCC_ATOMIC_OPERATIONS
36 #define skip_level(ptr, level) (__atomic_load_n(ptr, __ATOMIC_RELAXED) < level)
37 #define set_level(ptr, val) __atomic_store_n(ptr, val, __ATOMIC_RELAXED)
39 #elif defined(HAVE_GCC_SYNC_OPERATIONS)
41 #define skip_level(ptr, level) (__sync_fetch_and_add(ptr, 0) < level)
42 #define set_level(ptr, val) __sync_bool_compare_and_swap(ptr, *ptr, val)
46 #define skip_level(ptr, level) FALSE
47 #define set_level(ptr, val) ({ *ptr = val; })
51 typedef struct private_bus_t private_bus_t
;
54 * Private data of a bus_t object.
56 struct private_bus_t
{
58 * Public part of a bus_t object.
63 * List of registered listeners as entry_t.
65 linked_list_t
*listeners
;
68 * List of registered loggers for each log group as log_entry_t.
69 * Loggers are ordered by descending log level.
70 * The extra list stores all loggers so we can properly unregister them.
72 linked_list_t
*loggers
[DBG_MAX
+ 1];
75 * Maximum log level of any registered logger for each log group.
76 * This allows to check quickly if a log message has to be logged at all.
78 level_t max_level
[DBG_MAX
+ 1];
81 * Same as max level, but for loggers using the vlog() method.
83 level_t max_vlevel
[DBG_MAX
+ 1];
86 * Mutex for the list of listeners, recursively.
91 * Read-write lock for the list of loggers.
96 * Thread local storage the threads IKE_SA
98 thread_value_t
*thread_sa
;
101 typedef struct entry_t entry_t
;
109 * registered listener interface
111 listener_t
*listener
;
114 * are we currently calling this listener
120 typedef struct log_entry_t log_entry_t
;
128 * registered logger interface
133 * registered log levels per group
135 level_t levels
[DBG_MAX
];
139 METHOD(bus_t
, add_listener
, void,
140 private_bus_t
*this, listener_t
*listener
)
145 .listener
= listener
,
148 this->mutex
->lock(this->mutex
);
149 this->listeners
->insert_last(this->listeners
, entry
);
150 this->mutex
->unlock(this->mutex
);
153 METHOD(bus_t
, remove_listener
, void,
154 private_bus_t
*this, listener_t
*listener
)
156 enumerator_t
*enumerator
;
159 this->mutex
->lock(this->mutex
);
160 enumerator
= this->listeners
->create_enumerator(this->listeners
);
161 while (enumerator
->enumerate(enumerator
, &entry
))
163 if (entry
->listener
== listener
)
165 this->listeners
->remove_at(this->listeners
, enumerator
);
170 enumerator
->destroy(enumerator
);
171 this->mutex
->unlock(this->mutex
);
175 * Register a logger on the given log group according to the requested level
177 static inline void register_logger(private_bus_t
*this, debug_t group
,
180 enumerator_t
*enumerator
;
181 linked_list_t
*loggers
;
182 log_entry_t
*current
;
185 loggers
= this->loggers
[group
];
186 level
= entry
->levels
[group
];
188 enumerator
= loggers
->create_enumerator(loggers
);
189 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
191 if (current
->levels
[group
] <= level
)
196 loggers
->insert_before(loggers
, enumerator
, entry
);
197 enumerator
->destroy(enumerator
);
199 if (entry
->logger
->log
)
201 set_level(&this->max_level
[group
], max(this->max_level
[group
], level
));
203 if (entry
->logger
->vlog
)
205 set_level(&this->max_vlevel
[group
],
206 max(this->max_vlevel
[group
], level
));
210 CALLBACK(find_max_levels
, bool,
211 log_entry_t
*entry
, va_list args
)
213 level_t
*level
, *vlevel
;
216 VA_ARGS_VGET(args
, group
, level
, vlevel
);
217 if (entry
->logger
->log
&& *level
== LEVEL_SILENT
)
219 *level
= entry
->levels
[group
];
221 if (entry
->logger
->vlog
&& *vlevel
== LEVEL_SILENT
)
223 *vlevel
= entry
->levels
[group
];
225 return *level
> LEVEL_SILENT
&& *vlevel
> LEVEL_SILENT
;
229 * Unregister a logger from all log groups (destroys the log_entry_t)
231 static inline void unregister_logger(private_bus_t
*this, logger_t
*logger
)
233 enumerator_t
*enumerator
;
234 linked_list_t
*loggers
;
235 log_entry_t
*entry
, *found
= NULL
;
238 loggers
= this->loggers
[DBG_MAX
];
239 enumerator
= loggers
->create_enumerator(loggers
);
240 while (enumerator
->enumerate(enumerator
, &entry
))
242 if (entry
->logger
== logger
)
244 loggers
->remove_at(loggers
, enumerator
);
249 enumerator
->destroy(enumerator
);
253 for (group
= 0; group
< DBG_MAX
; group
++)
255 if (found
->levels
[group
] > LEVEL_SILENT
)
257 level_t level
= LEVEL_SILENT
, vlevel
= LEVEL_SILENT
;
259 loggers
= this->loggers
[group
];
260 loggers
->remove(loggers
, found
, NULL
);
261 loggers
->find_first(loggers
, find_max_levels
, NULL
, group
,
263 set_level(&this->max_level
[group
], level
);
264 set_level(&this->max_vlevel
[group
], vlevel
);
271 METHOD(bus_t
, add_logger
, void,
272 private_bus_t
*this, logger_t
*logger
)
281 this->log_lock
->write_lock(this->log_lock
);
282 unregister_logger(this, logger
);
283 for (group
= 0; group
< DBG_MAX
; group
++)
285 entry
->levels
[group
] = logger
->get_level(logger
, group
);
286 if (entry
->levels
[group
] > LEVEL_SILENT
)
288 register_logger(this, group
, entry
);
291 this->loggers
[DBG_MAX
]->insert_last(this->loggers
[DBG_MAX
], entry
);
292 this->log_lock
->unlock(this->log_lock
);
295 METHOD(bus_t
, remove_logger
, void,
296 private_bus_t
*this, logger_t
*logger
)
298 this->log_lock
->write_lock(this->log_lock
);
299 unregister_logger(this, logger
);
300 this->log_lock
->unlock(this->log_lock
);
303 METHOD(bus_t
, set_sa
, void,
304 private_bus_t
*this, ike_sa_t
*ike_sa
)
306 this->thread_sa
->set(this->thread_sa
, ike_sa
);
309 METHOD(bus_t
, get_sa
, ike_sa_t
*,
312 return this->thread_sa
->get(this->thread_sa
);
316 * data associated to a signal, passed to callback
319 /** associated IKE_SA */
321 /** invoking thread */
329 /** argument list if message is a format string for vlog() */
333 CALLBACK(log_cb
, void,
334 log_entry_t
*entry
, va_list args
)
338 VA_ARGS_VGET(args
, data
);
339 if (entry
->logger
->log
&& entry
->levels
[data
->group
] >= data
->level
)
341 entry
->logger
->log(entry
->logger
, data
->group
, data
->level
,
342 data
->thread
, data
->ike_sa
, data
->message
);
346 CALLBACK(vlog_cb
, void,
347 log_entry_t
*entry
, va_list args
)
351 VA_ARGS_VGET(args
, data
);
352 if (entry
->logger
->vlog
&& entry
->levels
[data
->group
] >= data
->level
)
356 va_copy(copy
, data
->args
);
357 entry
->logger
->vlog(entry
->logger
, data
->group
, data
->level
,
358 data
->thread
, data
->ike_sa
, data
->message
, copy
);
363 METHOD(bus_t
, vlog
, void,
364 private_bus_t
*this, debug_t group
, level_t level
,
365 char* format
, va_list args
)
367 linked_list_t
*loggers
;
370 /* NOTE: This is not 100% thread-safe and done here only because it is
371 * performance critical. We therefore ignore the following two issues for
372 * this particular case: 1) We might miss some log messages if another
373 * thread concurrently increases the log level or registers a new logger.
374 * 2) We might have to acquire the read lock below even if it wouldn't be
375 * necessary anymore due to another thread concurrently unregistering a
376 * logger or reducing the level. */
377 if (skip_level(&this->max_level
[group
], level
) &&
378 skip_level(&this->max_vlevel
[group
], level
))
383 this->log_lock
->read_lock(this->log_lock
);
384 loggers
= this->loggers
[group
];
386 if (this->max_level
[group
] >= level
)
391 data
.ike_sa
= this->thread_sa
->get(this->thread_sa
);
392 data
.thread
= thread_current_id();
397 va_copy(data
.args
, args
);
398 len
= vsnprintf(data
.message
, sizeof(buf
), format
, data
.args
);
400 if (len
>= sizeof(buf
))
403 data
.message
= malloc(len
);
404 va_copy(data
.args
, args
);
405 len
= vsnprintf(data
.message
, len
, format
, data
.args
);
410 loggers
->invoke_function(loggers
, log_cb
, &data
);
412 if (data
.message
!= buf
)
417 if (this->max_vlevel
[group
] >= level
)
419 data
.ike_sa
= this->thread_sa
->get(this->thread_sa
);
420 data
.thread
= thread_current_id();
423 data
.message
= format
;
425 va_copy(data
.args
, args
);
426 loggers
->invoke_function(loggers
, vlog_cb
, &data
);
430 this->log_lock
->unlock(this->log_lock
);
433 METHOD(bus_t
, log_
, void,
434 private_bus_t
*this, debug_t group
, level_t level
, char* format
, ...)
438 va_start(args
, format
);
439 vlog(this, group
, level
, format
, args
);
444 * unregister a listener
446 static inline void unregister_listener(private_bus_t
*this, entry_t
*entry
,
447 enumerator_t
*enumerator
)
449 this->listeners
->remove_at(this->listeners
, enumerator
);
453 METHOD(bus_t
, alert
, void,
454 private_bus_t
*this, alert_t alert
, ...)
456 enumerator_t
*enumerator
;
462 ike_sa
= this->thread_sa
->get(this->thread_sa
);
464 this->mutex
->lock(this->mutex
);
465 enumerator
= this->listeners
->create_enumerator(this->listeners
);
466 while (enumerator
->enumerate(enumerator
, &entry
))
468 if (entry
->calling
|| !entry
->listener
->alert
)
473 va_start(args
, alert
);
474 keep
= entry
->listener
->alert(entry
->listener
, ike_sa
, alert
, args
);
479 unregister_listener(this, entry
, enumerator
);
482 enumerator
->destroy(enumerator
);
483 this->mutex
->unlock(this->mutex
);
486 METHOD(bus_t
, ike_state_change
, void,
487 private_bus_t
*this, ike_sa_t
*ike_sa
, ike_sa_state_t state
)
489 enumerator_t
*enumerator
;
493 this->mutex
->lock(this->mutex
);
494 enumerator
= this->listeners
->create_enumerator(this->listeners
);
495 while (enumerator
->enumerate(enumerator
, &entry
))
497 if (entry
->calling
|| !entry
->listener
->ike_state_change
)
502 keep
= entry
->listener
->ike_state_change(entry
->listener
, ike_sa
, state
);
506 unregister_listener(this, entry
, enumerator
);
509 enumerator
->destroy(enumerator
);
510 this->mutex
->unlock(this->mutex
);
513 METHOD(bus_t
, child_state_change
, void,
514 private_bus_t
*this, child_sa_t
*child_sa
, child_sa_state_t state
)
516 enumerator_t
*enumerator
;
521 ike_sa
= this->thread_sa
->get(this->thread_sa
);
523 this->mutex
->lock(this->mutex
);
524 enumerator
= this->listeners
->create_enumerator(this->listeners
);
525 while (enumerator
->enumerate(enumerator
, &entry
))
527 if (entry
->calling
|| !entry
->listener
->child_state_change
)
532 keep
= entry
->listener
->child_state_change(entry
->listener
, ike_sa
,
537 unregister_listener(this, entry
, enumerator
);
540 enumerator
->destroy(enumerator
);
541 this->mutex
->unlock(this->mutex
);
544 METHOD(bus_t
, message
, void,
545 private_bus_t
*this, message_t
*message
, bool incoming
, bool plain
)
547 enumerator_t
*enumerator
;
552 ike_sa
= this->thread_sa
->get(this->thread_sa
);
554 this->mutex
->lock(this->mutex
);
555 enumerator
= this->listeners
->create_enumerator(this->listeners
);
556 while (enumerator
->enumerate(enumerator
, &entry
))
558 if (entry
->calling
|| !entry
->listener
->message
)
563 keep
= entry
->listener
->message(entry
->listener
, ike_sa
,
564 message
, incoming
, plain
);
568 unregister_listener(this, entry
, enumerator
);
571 enumerator
->destroy(enumerator
);
572 this->mutex
->unlock(this->mutex
);
575 METHOD(bus_t
, ike_keys
, void,
576 private_bus_t
*this, ike_sa_t
*ike_sa
, diffie_hellman_t
*dh
,
577 chunk_t dh_other
, chunk_t nonce_i
, chunk_t nonce_r
,
578 ike_sa_t
*rekey
, shared_key_t
*shared
)
580 enumerator_t
*enumerator
;
584 this->mutex
->lock(this->mutex
);
585 enumerator
= this->listeners
->create_enumerator(this->listeners
);
586 while (enumerator
->enumerate(enumerator
, &entry
))
588 if (entry
->calling
|| !entry
->listener
->ike_keys
)
593 keep
= entry
->listener
->ike_keys(entry
->listener
, ike_sa
, dh
, dh_other
,
594 nonce_i
, nonce_r
, rekey
, shared
);
598 unregister_listener(this, entry
, enumerator
);
601 enumerator
->destroy(enumerator
);
602 this->mutex
->unlock(this->mutex
);
605 METHOD(bus_t
, ike_derived_keys
, void,
606 private_bus_t
*this, chunk_t sk_ei
, chunk_t sk_er
, chunk_t sk_ai
,
609 enumerator_t
*enumerator
;
614 ike_sa
= this->thread_sa
->get(this->thread_sa
);
616 this->mutex
->lock(this->mutex
);
617 enumerator
= this->listeners
->create_enumerator(this->listeners
);
618 while (enumerator
->enumerate(enumerator
, &entry
))
620 if (entry
->calling
|| !entry
->listener
->ike_derived_keys
)
625 keep
= entry
->listener
->ike_derived_keys(entry
->listener
, ike_sa
, sk_ei
,
626 sk_er
, sk_ai
, sk_ar
);
630 unregister_listener(this, entry
, enumerator
);
633 enumerator
->destroy(enumerator
);
634 this->mutex
->unlock(this->mutex
);
637 METHOD(bus_t
, child_keys
, void,
638 private_bus_t
*this, child_sa_t
*child_sa
, bool initiator
,
639 diffie_hellman_t
*dh
, chunk_t nonce_i
, chunk_t nonce_r
)
641 enumerator_t
*enumerator
;
646 ike_sa
= this->thread_sa
->get(this->thread_sa
);
648 this->mutex
->lock(this->mutex
);
649 enumerator
= this->listeners
->create_enumerator(this->listeners
);
650 while (enumerator
->enumerate(enumerator
, &entry
))
652 if (entry
->calling
|| !entry
->listener
->child_keys
)
657 keep
= entry
->listener
->child_keys(entry
->listener
, ike_sa
,
658 child_sa
, initiator
, dh
, nonce_i
, nonce_r
);
662 unregister_listener(this, entry
, enumerator
);
665 enumerator
->destroy(enumerator
);
666 this->mutex
->unlock(this->mutex
);
669 METHOD(bus_t
, child_derived_keys
, void,
670 private_bus_t
*this, child_sa_t
*child_sa
, bool initiator
,
671 chunk_t encr_i
, chunk_t encr_r
, chunk_t integ_i
, chunk_t integ_r
)
673 enumerator_t
*enumerator
;
678 ike_sa
= this->thread_sa
->get(this->thread_sa
);
680 this->mutex
->lock(this->mutex
);
681 enumerator
= this->listeners
->create_enumerator(this->listeners
);
682 while (enumerator
->enumerate(enumerator
, &entry
))
684 if (entry
->calling
|| !entry
->listener
->child_derived_keys
)
689 keep
= entry
->listener
->child_derived_keys(entry
->listener
, ike_sa
,
690 child_sa
, initiator
, encr_i
, encr_r
,
695 unregister_listener(this, entry
, enumerator
);
698 enumerator
->destroy(enumerator
);
699 this->mutex
->unlock(this->mutex
);
702 METHOD(bus_t
, child_updown
, void,
703 private_bus_t
*this, child_sa_t
*child_sa
, bool up
)
705 enumerator_t
*enumerator
;
710 ike_sa
= this->thread_sa
->get(this->thread_sa
);
712 this->mutex
->lock(this->mutex
);
713 enumerator
= this->listeners
->create_enumerator(this->listeners
);
714 while (enumerator
->enumerate(enumerator
, &entry
))
716 if (entry
->calling
|| !entry
->listener
->child_updown
)
721 keep
= entry
->listener
->child_updown(entry
->listener
,
722 ike_sa
, child_sa
, up
);
726 unregister_listener(this, entry
, enumerator
);
729 enumerator
->destroy(enumerator
);
730 this->mutex
->unlock(this->mutex
);
733 METHOD(bus_t
, child_rekey
, void,
734 private_bus_t
*this, child_sa_t
*old
, child_sa_t
*new)
736 enumerator_t
*enumerator
;
741 ike_sa
= this->thread_sa
->get(this->thread_sa
);
743 this->mutex
->lock(this->mutex
);
744 enumerator
= this->listeners
->create_enumerator(this->listeners
);
745 while (enumerator
->enumerate(enumerator
, &entry
))
747 if (entry
->calling
|| !entry
->listener
->child_rekey
)
752 keep
= entry
->listener
->child_rekey(entry
->listener
, ike_sa
,
757 unregister_listener(this, entry
, enumerator
);
760 enumerator
->destroy(enumerator
);
761 this->mutex
->unlock(this->mutex
);
764 METHOD(bus_t
, children_migrate
, void,
765 private_bus_t
*this, ike_sa_id_t
*new, uint32_t unique
)
767 enumerator_t
*enumerator
;
772 ike_sa
= this->thread_sa
->get(this->thread_sa
);
774 this->mutex
->lock(this->mutex
);
775 enumerator
= this->listeners
->create_enumerator(this->listeners
);
776 while (enumerator
->enumerate(enumerator
, &entry
))
778 if (entry
->calling
|| !entry
->listener
->children_migrate
)
783 keep
= entry
->listener
->children_migrate(entry
->listener
, ike_sa
, new,
788 unregister_listener(this, entry
, enumerator
);
791 enumerator
->destroy(enumerator
);
792 this->mutex
->unlock(this->mutex
);
795 METHOD(bus_t
, ike_updown
, void,
796 private_bus_t
*this, ike_sa_t
*ike_sa
, bool up
)
798 enumerator_t
*enumerator
;
802 this->mutex
->lock(this->mutex
);
803 enumerator
= this->listeners
->create_enumerator(this->listeners
);
804 while (enumerator
->enumerate(enumerator
, &entry
))
806 if (entry
->calling
|| !entry
->listener
->ike_updown
)
811 keep
= entry
->listener
->ike_updown(entry
->listener
, ike_sa
, up
);
815 unregister_listener(this, entry
, enumerator
);
818 enumerator
->destroy(enumerator
);
819 this->mutex
->unlock(this->mutex
);
821 /* a down event for IKE_SA implicitly downs all CHILD_SAs */
824 enumerator_t
*enumerator
;
825 child_sa_t
*child_sa
;
827 enumerator
= ike_sa
->create_child_sa_enumerator(ike_sa
);
828 while (enumerator
->enumerate(enumerator
, (void**)&child_sa
))
830 if (child_sa
->get_state(child_sa
) != CHILD_REKEYED
)
832 child_updown(this, child_sa
, FALSE
);
835 enumerator
->destroy(enumerator
);
839 METHOD(bus_t
, ike_rekey
, void,
840 private_bus_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
842 enumerator_t
*enumerator
;
846 this->mutex
->lock(this->mutex
);
847 enumerator
= this->listeners
->create_enumerator(this->listeners
);
848 while (enumerator
->enumerate(enumerator
, &entry
))
850 if (entry
->calling
|| !entry
->listener
->ike_rekey
)
855 keep
= entry
->listener
->ike_rekey(entry
->listener
, old
, new);
859 unregister_listener(this, entry
, enumerator
);
862 enumerator
->destroy(enumerator
);
863 this->mutex
->unlock(this->mutex
);
866 METHOD(bus_t
, ike_update
, void,
867 private_bus_t
*this, ike_sa_t
*ike_sa
, bool local
, host_t
*new)
869 enumerator_t
*enumerator
;
873 this->mutex
->lock(this->mutex
);
874 enumerator
= this->listeners
->create_enumerator(this->listeners
);
875 while (enumerator
->enumerate(enumerator
, &entry
))
877 if (entry
->calling
|| !entry
->listener
->ike_update
)
882 keep
= entry
->listener
->ike_update(entry
->listener
, ike_sa
, local
, new);
886 unregister_listener(this, entry
, enumerator
);
889 enumerator
->destroy(enumerator
);
890 this->mutex
->unlock(this->mutex
);
893 METHOD(bus_t
, ike_reestablish_pre
, void,
894 private_bus_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
896 enumerator_t
*enumerator
;
900 this->mutex
->lock(this->mutex
);
901 enumerator
= this->listeners
->create_enumerator(this->listeners
);
902 while (enumerator
->enumerate(enumerator
, &entry
))
904 if (entry
->calling
|| !entry
->listener
->ike_reestablish_pre
)
909 keep
= entry
->listener
->ike_reestablish_pre(entry
->listener
, old
, new);
913 unregister_listener(this, entry
, enumerator
);
916 enumerator
->destroy(enumerator
);
917 this->mutex
->unlock(this->mutex
);
920 METHOD(bus_t
, ike_reestablish_post
, void,
921 private_bus_t
*this, ike_sa_t
*old
, ike_sa_t
*new, bool initiated
)
923 enumerator_t
*enumerator
;
927 this->mutex
->lock(this->mutex
);
928 enumerator
= this->listeners
->create_enumerator(this->listeners
);
929 while (enumerator
->enumerate(enumerator
, &entry
))
931 if (entry
->calling
|| !entry
->listener
->ike_reestablish_post
)
936 keep
= entry
->listener
->ike_reestablish_post(entry
->listener
, old
, new,
941 unregister_listener(this, entry
, enumerator
);
944 enumerator
->destroy(enumerator
);
945 this->mutex
->unlock(this->mutex
);
948 METHOD(bus_t
, authorize
, bool,
949 private_bus_t
*this, bool final
)
951 enumerator_t
*enumerator
;
954 bool keep
, success
= TRUE
;
956 ike_sa
= this->thread_sa
->get(this->thread_sa
);
958 this->mutex
->lock(this->mutex
);
959 enumerator
= this->listeners
->create_enumerator(this->listeners
);
960 while (enumerator
->enumerate(enumerator
, &entry
))
962 if (entry
->calling
|| !entry
->listener
->authorize
)
967 keep
= entry
->listener
->authorize(entry
->listener
, ike_sa
,
972 unregister_listener(this, entry
, enumerator
);
979 enumerator
->destroy(enumerator
);
980 this->mutex
->unlock(this->mutex
);
983 alert(this, ALERT_AUTHORIZATION_FAILED
);
988 METHOD(bus_t
, narrow
, void,
989 private_bus_t
*this, child_sa_t
*child_sa
, narrow_hook_t type
,
990 linked_list_t
*local
, linked_list_t
*remote
)
992 enumerator_t
*enumerator
;
997 ike_sa
= this->thread_sa
->get(this->thread_sa
);
999 this->mutex
->lock(this->mutex
);
1000 enumerator
= this->listeners
->create_enumerator(this->listeners
);
1001 while (enumerator
->enumerate(enumerator
, &entry
))
1003 if (entry
->calling
|| !entry
->listener
->narrow
)
1008 keep
= entry
->listener
->narrow(entry
->listener
, ike_sa
, child_sa
,
1009 type
, local
, remote
);
1013 unregister_listener(this, entry
, enumerator
);
1016 enumerator
->destroy(enumerator
);
1017 this->mutex
->unlock(this->mutex
);
1020 METHOD(bus_t
, assign_vips
, void,
1021 private_bus_t
*this, ike_sa_t
*ike_sa
, bool assign
)
1023 enumerator_t
*enumerator
;
1027 this->mutex
->lock(this->mutex
);
1028 enumerator
= this->listeners
->create_enumerator(this->listeners
);
1029 while (enumerator
->enumerate(enumerator
, &entry
))
1031 if (entry
->calling
|| !entry
->listener
->assign_vips
)
1036 keep
= entry
->listener
->assign_vips(entry
->listener
, ike_sa
, assign
);
1040 unregister_listener(this, entry
, enumerator
);
1043 enumerator
->destroy(enumerator
);
1044 this->mutex
->unlock(this->mutex
);
1047 METHOD(bus_t
, handle_vips
, void,
1048 private_bus_t
*this, ike_sa_t
*ike_sa
, bool handle
)
1050 enumerator_t
*enumerator
;
1054 this->mutex
->lock(this->mutex
);
1055 enumerator
= this->listeners
->create_enumerator(this->listeners
);
1056 while (enumerator
->enumerate(enumerator
, &entry
))
1058 if (entry
->calling
|| !entry
->listener
->handle_vips
)
1063 keep
= entry
->listener
->handle_vips(entry
->listener
, ike_sa
, handle
);
1067 unregister_listener(this, entry
, enumerator
);
1070 enumerator
->destroy(enumerator
);
1071 this->mutex
->unlock(this->mutex
);
1075 * Credential manager hook function to forward bus alerts
1077 static void hook_creds(private_bus_t
*this, credential_hook_type_t type
,
1078 certificate_t
*cert
)
1082 case CRED_HOOK_EXPIRED
:
1083 return alert(this, ALERT_CERT_EXPIRED
, cert
);
1084 case CRED_HOOK_REVOKED
:
1085 return alert(this, ALERT_CERT_REVOKED
, cert
);
1086 case CRED_HOOK_VALIDATION_FAILED
:
1087 return alert(this, ALERT_CERT_VALIDATION_FAILED
, cert
);
1088 case CRED_HOOK_NO_ISSUER
:
1089 return alert(this, ALERT_CERT_NO_ISSUER
, cert
);
1090 case CRED_HOOK_UNTRUSTED_ROOT
:
1091 return alert(this, ALERT_CERT_UNTRUSTED_ROOT
, cert
);
1092 case CRED_HOOK_EXCEEDED_PATH_LEN
:
1093 return alert(this, ALERT_CERT_EXCEEDED_PATH_LEN
, cert
);
1094 case CRED_HOOK_POLICY_VIOLATION
:
1095 return alert(this, ALERT_CERT_POLICY_VIOLATION
, cert
);
1099 METHOD(bus_t
, destroy
, void,
1100 private_bus_t
*this)
1104 lib
->credmgr
->set_hook(lib
->credmgr
, NULL
, NULL
);
1105 for (group
= 0; group
< DBG_MAX
; group
++)
1107 this->loggers
[group
]->destroy(this->loggers
[group
]);
1109 this->loggers
[DBG_MAX
]->destroy_function(this->loggers
[DBG_MAX
],
1111 this->listeners
->destroy_function(this->listeners
, (void*)free
);
1112 this->thread_sa
->destroy(this->thread_sa
);
1113 this->log_lock
->destroy(this->log_lock
);
1114 this->mutex
->destroy(this->mutex
);
1119 * Described in header.
1123 private_bus_t
*this;
1128 .add_listener
= _add_listener
,
1129 .remove_listener
= _remove_listener
,
1130 .add_logger
= _add_logger
,
1131 .remove_logger
= _remove_logger
,
1137 .ike_state_change
= _ike_state_change
,
1138 .child_state_change
= _child_state_change
,
1139 .message
= _message
,
1140 .ike_keys
= _ike_keys
,
1141 .ike_derived_keys
= _ike_derived_keys
,
1142 .child_keys
= _child_keys
,
1143 .child_derived_keys
= _child_derived_keys
,
1144 .ike_updown
= _ike_updown
,
1145 .ike_rekey
= _ike_rekey
,
1146 .ike_update
= _ike_update
,
1147 .ike_reestablish_pre
= _ike_reestablish_pre
,
1148 .ike_reestablish_post
= _ike_reestablish_post
,
1149 .child_updown
= _child_updown
,
1150 .child_rekey
= _child_rekey
,
1151 .children_migrate
= _children_migrate
,
1152 .authorize
= _authorize
,
1154 .assign_vips
= _assign_vips
,
1155 .handle_vips
= _handle_vips
,
1156 .destroy
= _destroy
,
1158 .listeners
= linked_list_create(),
1159 .mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
),
1160 .log_lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
1161 .thread_sa
= thread_value_create(NULL
),
1164 for (group
= 0; group
<= DBG_MAX
; group
++)
1166 this->loggers
[group
] = linked_list_create();
1167 this->max_level
[group
] = LEVEL_SILENT
;
1168 this->max_vlevel
[group
] = LEVEL_SILENT
;
1171 lib
->credmgr
->set_hook(lib
->credmgr
, (credential_hook_t
)hook_creds
, this);
1173 return &this->public;