pluto: Listen for kernel events via libhydra's kernel interface.
This commit is contained in:
+84
-11
@@ -38,6 +38,7 @@
|
|||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <hydra.h>
|
#include <hydra.h>
|
||||||
#include <crypto/rngs/rng.h>
|
#include <crypto/rngs/rng.h>
|
||||||
|
#include <kernel/kernel_listener.h>
|
||||||
|
|
||||||
#ifdef KLIPS
|
#ifdef KLIPS
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
#include "nat_traversal.h"
|
#include "nat_traversal.h"
|
||||||
#include "alg_info.h"
|
#include "alg_info.h"
|
||||||
#include "kernel_alg.h"
|
#include "kernel_alg.h"
|
||||||
|
#include "pluto.h"
|
||||||
|
|
||||||
|
|
||||||
bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */
|
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;
|
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,
|
void record_and_initiate_opportunistic(const ip_subnet *ours,
|
||||||
const ip_subnet *his,
|
const ip_subnet *his,
|
||||||
int transport_proto, const char *why)
|
int transport_proto, const char *why)
|
||||||
@@ -1773,18 +1791,64 @@ failed:
|
|||||||
|
|
||||||
const struct kernel_ops *kernel_ops;
|
const struct kernel_ops *kernel_ops;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data for acquire events
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** Subnets */
|
||||||
|
ip_subnet src, dst;
|
||||||
|
/** Transport protocol */
|
||||||
|
int proto;
|
||||||
|
} acquire_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for acquire events (called by main thread)
|
||||||
|
*/
|
||||||
|
void handle_acquire(acquire_data_t *this)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 */
|
#endif /* KLIPS */
|
||||||
|
|
||||||
void init_kernel(void)
|
void init_kernel(void)
|
||||||
{
|
{
|
||||||
#ifdef KLIPS
|
#ifdef KLIPS
|
||||||
|
|
||||||
if (no_klips)
|
|
||||||
{
|
|
||||||
kernel_ops = &noklips_kernel_ops;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_pfkey();
|
init_pfkey();
|
||||||
|
|
||||||
kernel_ops = &klips_kernel_ops;
|
kernel_ops = &klips_kernel_ops;
|
||||||
@@ -1807,14 +1871,23 @@ void init_kernel(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (kernel_ops->init)
|
|
||||||
{
|
|
||||||
kernel_ops->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register SA types that we can negotiate */
|
/* register SA types that we can negotiate */
|
||||||
can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
|
can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
|
||||||
kernel_ops->pfkey_register();
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ extern void record_and_initiate_opportunistic(const ip_subnet *
|
|||||||
, const char *why);
|
, const char *why);
|
||||||
|
|
||||||
extern void init_kernel(void);
|
extern void init_kernel(void);
|
||||||
|
extern void kernel_finalize(void);
|
||||||
|
|
||||||
extern bool trap_connection(struct connection *c);
|
extern bool trap_connection(struct connection *c);
|
||||||
extern void unroute_connection(struct connection *c);
|
extern void unroute_connection(struct connection *c);
|
||||||
|
|||||||
@@ -786,6 +786,7 @@ void exit_pluto(int status)
|
|||||||
free_remembered_public_keys();
|
free_remembered_public_keys();
|
||||||
delete_every_connection();
|
delete_every_connection();
|
||||||
whack_attribute_finalize(); /* free in-memory pools */
|
whack_attribute_finalize(); /* free in-memory pools */
|
||||||
|
kernel_finalize();
|
||||||
fetch_finalize(); /* stop fetching thread */
|
fetch_finalize(); /* stop fetching thread */
|
||||||
free_crl_fetch(); /* free chain of crl fetch requests */
|
free_crl_fetch(); /* free chain of crl fetch requests */
|
||||||
free_ocsp_fetch(); /* free chain of ocsp fetch requests */
|
free_ocsp_fetch(); /* free chain of ocsp fetch requests */
|
||||||
|
|||||||
@@ -859,20 +859,6 @@ call_server(void)
|
|||||||
maxfd = events_fd;
|
maxfd = events_fd;
|
||||||
FD_SET(events_fd, &readfds);
|
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)
|
if (listening)
|
||||||
{
|
{
|
||||||
for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
|
for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
|
||||||
@@ -964,19 +950,6 @@ call_server(void)
|
|||||||
ndes--;
|
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)
|
for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
|
||||||
{
|
{
|
||||||
if (FD_ISSET(ifp->fd, &readfds))
|
if (FD_ISSET(ifp->fd, &readfds))
|
||||||
|
|||||||
Reference in New Issue
Block a user