diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pluto/kernel.c | 95 | ||||
-rw-r--r-- | src/pluto/kernel.h | 1 | ||||
-rw-r--r-- | src/pluto/plutomain.c | 1 | ||||
-rw-r--r-- | src/pluto/server.c | 27 |
4 files changed, 86 insertions, 38 deletions
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c index 690f28a2d..164e42833 100644 --- a/src/pluto/kernel.c +++ b/src/pluto/kernel.c @@ -38,6 +38,7 @@ #include <library.h> #include <hydra.h> #include <crypto/rngs/rng.h> +#include <kernel/kernel_listener.h> #ifdef KLIPS #include <signal.h> @@ -66,6 +67,7 @@ #include "nat_traversal.h" #include "alg_info.h" #include "kernel_alg.h" +#include "pluto.h" bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */ @@ -182,6 +184,22 @@ static traffic_selector_t *traffic_selector_from_subnet(const ip_subnet *client, return ts; } +/** + * Helper function that converts a traffic_selector_t to an ip_subnet. + */ +static ip_subnet subnet_from_traffic_selector(traffic_selector_t *ts) +{ + ip_subnet subnet; + host_t *net; + u_int8_t mask; + ts->to_subnet(ts, &net, &mask); + subnet.addr = *(ip_address*)net->get_sockaddr(net); + subnet.maskbits = mask; + net->destroy(net); + return subnet; +} + + void record_and_initiate_opportunistic(const ip_subnet *ours, const ip_subnet *his, int transport_proto, const char *why) @@ -1773,17 +1791,63 @@ failed: const struct kernel_ops *kernel_ops; -#endif /* KLIPS */ +/** + * Data for acquire events + */ +typedef struct { + /** Subnets */ + ip_subnet src, dst; + /** Transport protocol */ + int proto; +} acquire_data_t; -void init_kernel(void) +/** + * Callback for acquire events (called by main thread) + */ +void handle_acquire(acquire_data_t *this) { -#ifdef KLIPS + record_and_initiate_opportunistic(&this->src, &this->dst, this->proto, + "%acquire"); +} + +/** + * Handler for kernel events (called by thread-pool thread) + */ +kernel_listener_t *kernel_handler; - if (no_klips) +METHOD(kernel_listener_t, acquire, bool, + kernel_listener_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts) +{ + if (src_ts && dst_ts) { - kernel_ops = &noklips_kernel_ops; - return; + acquire_data_t *data; + DBG(DBG_CONTROL, + DBG_log("creating acquire event for policy %R === %R " + "with reqid {%u}", src_ts, dst_ts, reqid)); + INIT(data, + .src = subnet_from_traffic_selector(src_ts), + .dst = subnet_from_traffic_selector(dst_ts), + .proto = src_ts->get_protocol(src_ts), + ); + pluto->events->queue(pluto->events, (void*)handle_acquire, data, free); } + else + { + DBG(DBG_CONTROL, + DBG_log("ignoring acquire without traffic selectors for policy " + "with reqid {%u}", reqid)); + } + DESTROY_IF(src_ts); + DESTROY_IF(dst_ts); + return TRUE; +} + +#endif /* KLIPS */ + +void init_kernel(void) +{ +#ifdef KLIPS init_pfkey(); @@ -1807,14 +1871,23 @@ void init_kernel(void) } #endif - if (kernel_ops->init) - { - kernel_ops->init(); - } - /* register SA types that we can negotiate */ can_do_IPcomp = FALSE; /* until we get a response from KLIPS */ kernel_ops->pfkey_register(); + + INIT(kernel_handler, + .acquire = _acquire, + ); + hydra->kernel_interface->add_listener(hydra->kernel_interface, + kernel_handler); +#endif +} + +void kernel_finalize() +{ +#ifdef KLIPS + hydra->kernel_interface->remove_listener(hydra->kernel_interface, + kernel_handler); #endif } diff --git a/src/pluto/kernel.h b/src/pluto/kernel.h index 26efd0013..9b1d57a88 100644 --- a/src/pluto/kernel.h +++ b/src/pluto/kernel.h @@ -151,6 +151,7 @@ extern void record_and_initiate_opportunistic(const ip_subnet * , const char *why); extern void init_kernel(void); +extern void kernel_finalize(void); extern bool trap_connection(struct connection *c); extern void unroute_connection(struct connection *c); diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c index c172e8f3a..ecb4aa50e 100644 --- a/src/pluto/plutomain.c +++ b/src/pluto/plutomain.c @@ -786,6 +786,7 @@ void exit_pluto(int status) free_remembered_public_keys(); delete_every_connection(); whack_attribute_finalize(); /* free in-memory pools */ + kernel_finalize(); fetch_finalize(); /* stop fetching thread */ free_crl_fetch(); /* free chain of crl fetch requests */ free_ocsp_fetch(); /* free chain of ocsp fetch requests */ diff --git a/src/pluto/server.c b/src/pluto/server.c index 6ad49640d..1f90039a8 100644 --- a/src/pluto/server.c +++ b/src/pluto/server.c @@ -859,20 +859,6 @@ call_server(void) maxfd = events_fd; FD_SET(events_fd, &readfds); -#ifdef KLIPS - if (!no_klips) - { - int fd = *kernel_ops->async_fdp; - - if (kernel_ops->process_queue) - kernel_ops->process_queue(); - if (maxfd < fd) - maxfd = fd; - passert(!FD_ISSET(fd, &readfds)); - FD_SET(fd, &readfds); - } -#endif - if (listening) { for (ifp = interfaces; ifp != NULL; ifp = ifp->next) @@ -964,19 +950,6 @@ call_server(void) ndes--; } -#ifdef KLIPS - if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds)) - { - passert(ndes > 0); - DBG(DBG_CONTROL, - DBG_log(BLANK_FORMAT); - DBG_log("*received kernel message")); - kernel_ops->process_msg(); - passert(GLOBALS_ARE_RESET()); - ndes--; - } -#endif - for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { if (FD_ISSET(ifp->fd, &readfds)) |