reducing capabilities of the threads to a minimum
proper flush of pending packets on daemon shutdown adding local address as gateway address in dynamic route
This commit is contained in:
@@ -89,6 +89,79 @@ static void set_state(private_dbus_interface_t *this, NMVPNState state)
|
|||||||
this->state = state;
|
this->state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the child_cfg with the same name as the peer cfg
|
||||||
|
*/
|
||||||
|
static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
|
||||||
|
{
|
||||||
|
child_cfg_t *current, *found = NULL;
|
||||||
|
iterator_t *iterator;
|
||||||
|
|
||||||
|
iterator = peer_cfg->create_child_cfg_iterator(peer_cfg);
|
||||||
|
while (iterator->iterate(iterator, (void**)¤t))
|
||||||
|
{
|
||||||
|
if (streq(current->get_name(current), name))
|
||||||
|
{
|
||||||
|
found = current;
|
||||||
|
found->get_ref(found);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a peer configuration by its name, or a name of its children
|
||||||
|
*/
|
||||||
|
static peer_cfg_t *get_peer_cfg_by_name(char *name)
|
||||||
|
{
|
||||||
|
iterator_t *i1, *i2;
|
||||||
|
peer_cfg_t *current, *found = NULL;
|
||||||
|
child_cfg_t *child;
|
||||||
|
|
||||||
|
i1 = charon->backends->create_iterator(charon->backends);
|
||||||
|
while (i1->iterate(i1, (void**)¤t))
|
||||||
|
{
|
||||||
|
/* compare peer_cfgs name first */
|
||||||
|
if (streq(current->get_name(current), name))
|
||||||
|
{
|
||||||
|
found = current;
|
||||||
|
found->get_ref(found);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* compare all child_cfg names otherwise */
|
||||||
|
i2 = current->create_child_cfg_iterator(current);
|
||||||
|
while (i2->iterate(i2, (void**)&child))
|
||||||
|
{
|
||||||
|
if (streq(child->get_name(child), name))
|
||||||
|
{
|
||||||
|
found = current;
|
||||||
|
found->get_ref(found);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i2->destroy(i2);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i1->destroy(i1);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logging dummy
|
||||||
|
*/
|
||||||
|
static bool dbus_log(void *param, signal_t signal, level_t level,
|
||||||
|
ike_sa_t *ike_sa, char *format, va_list args)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* process NetworkManagers startConnection method call
|
* process NetworkManagers startConnection method call
|
||||||
*/
|
*/
|
||||||
@@ -101,6 +174,9 @@ static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
|
|||||||
char *dev, *domain, *banner;
|
char *dev, *domain, *banner;
|
||||||
const dbus_int32_t array[] = {};
|
const dbus_int32_t array[] = {};
|
||||||
const dbus_int32_t *varray = array;
|
const dbus_int32_t *varray = array;
|
||||||
|
peer_cfg_t *peer_cfg;
|
||||||
|
child_cfg_t *child_cfg;
|
||||||
|
status_t status = FAILED;
|
||||||
|
|
||||||
if (!dbus_message_get_args(msg, &this->err,
|
if (!dbus_message_get_args(msg, &this->err,
|
||||||
DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user,
|
DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user,
|
||||||
@@ -113,13 +189,22 @@ static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
|
|||||||
}
|
}
|
||||||
set_state(this, NM_VPN_STATE_STARTING);
|
set_state(this, NM_VPN_STATE_STARTING);
|
||||||
|
|
||||||
reply = dbus_message_new_method_return(msg);
|
peer_cfg = get_peer_cfg_by_name(name);
|
||||||
dbus_connection_send(this->conn, reply, NULL);
|
if (peer_cfg)
|
||||||
|
{
|
||||||
|
child_cfg = get_child_from_peer(peer_cfg, name);
|
||||||
|
if (child_cfg)
|
||||||
|
{
|
||||||
|
status = charon->interfaces->initiate(charon->interfaces, peer_cfg,
|
||||||
|
child_cfg, dbus_log, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == SUCCESS)
|
||||||
|
{
|
||||||
signal = dbus_message_new_signal(NM_DBUS_PATH_STRONG,
|
signal = dbus_message_new_signal(NM_DBUS_PATH_STRONG,
|
||||||
NM_DBUS_INTERFACE_STRONG,
|
NM_DBUS_INTERFACE_STRONG,
|
||||||
NM_DBUS_VPN_SIGNAL_IP4_CONFIG);
|
NM_DBUS_VPN_SIGNAL_IP4_CONFIG);
|
||||||
|
|
||||||
me = other = p2p = mss = netmask = 0;
|
me = other = p2p = mss = netmask = 0;
|
||||||
dev = domain = banner = "";
|
dev = domain = banner = "";
|
||||||
if (dbus_message_append_args(signal,
|
if (dbus_message_append_args(signal,
|
||||||
@@ -132,14 +217,20 @@ static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
|
|||||||
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &varray, 0,
|
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &varray, 0,
|
||||||
DBUS_TYPE_UINT32, &mss,
|
DBUS_TYPE_UINT32, &mss,
|
||||||
DBUS_TYPE_STRING, &domain,
|
DBUS_TYPE_STRING, &domain,
|
||||||
DBUS_TYPE_STRING, &banner))
|
DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID))
|
||||||
{
|
{
|
||||||
dbus_connection_send(this->conn, signal, NULL);
|
dbus_connection_send(this->conn, signal, NULL);
|
||||||
}
|
}
|
||||||
dbus_message_unref(signal);
|
dbus_message_unref(signal);
|
||||||
|
|
||||||
set_state(this, NM_VPN_STATE_STARTED);
|
set_state(this, NM_VPN_STATE_STARTED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_state(this, NM_VPN_STATE_STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply = dbus_message_new_method_return(msg);
|
||||||
|
dbus_connection_send(this->conn, reply, NULL);
|
||||||
dbus_connection_flush(this->conn);
|
dbus_connection_flush(this->conn);
|
||||||
dbus_message_unref(reply);
|
dbus_message_unref(reply);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -247,6 +338,9 @@ static DBusHandlerResult signal_handler(DBusConnection *con, DBusMessage *msg,
|
|||||||
*/
|
*/
|
||||||
static void dispatch(private_dbus_interface_t *this)
|
static void dispatch(private_dbus_interface_t *this)
|
||||||
{
|
{
|
||||||
|
/* drop threads capabilities */
|
||||||
|
charon->drop_capabilities(charon, FALSE, FALSE);
|
||||||
|
|
||||||
while (dbus_connection_read_write_dispatch(this->conn, -1))
|
while (dbus_connection_read_write_dispatch(this->conn, -1))
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* nothing */
|
||||||
@@ -273,7 +367,7 @@ interface_t *interface_create()
|
|||||||
DBusObjectPathVTable v = {NULL, (void*)&message_handler, NULL, NULL, NULL, NULL};
|
DBusObjectPathVTable v = {NULL, (void*)&message_handler, NULL, NULL, NULL, NULL};
|
||||||
private_dbus_interface_t *this = malloc_thing(private_dbus_interface_t);
|
private_dbus_interface_t *this = malloc_thing(private_dbus_interface_t);
|
||||||
|
|
||||||
this->public.interface.destroy = (void (*)(dbus_interface_t*))destroy;
|
this->public.interface.destroy = (void (*)(interface_t*))destroy;
|
||||||
|
|
||||||
dbus_error_init(&this->err);
|
dbus_error_init(&this->err);
|
||||||
this->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this->err);
|
this->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this->err);
|
||||||
@@ -320,5 +414,5 @@ interface_t *interface_create()
|
|||||||
charon->kill(charon, "unable to create stroke thread");
|
charon->kill(charon, "unable to create stroke thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
return &this->public;
|
return &this->public.interface;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1528,6 +1528,9 @@ static void stroke_receive(private_stroke_interface_t *this)
|
|||||||
int oldstate;
|
int oldstate;
|
||||||
int strokefd;
|
int strokefd;
|
||||||
|
|
||||||
|
/* drop threads capabilities */
|
||||||
|
charon->drop_capabilities(charon, FALSE, FALSE);
|
||||||
|
|
||||||
/* ignore sigpipe. writing over the pipe back to the console
|
/* ignore sigpipe. writing over the pipe back to the console
|
||||||
* only fails if SIGPIPE is ignored. */
|
* only fails if SIGPIPE is ignored. */
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
@@ -1585,7 +1588,7 @@ interface_t *interface_create()
|
|||||||
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (this->socket == -1)
|
if (this->socket == -1)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "could not create whack socket");
|
DBG1(DBG_CFG, "could not create stroke socket");
|
||||||
free(this);
|
free(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1618,5 +1621,5 @@ interface_t *interface_create()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (interface_t*)(&this->public);
|
return &this->public.interface;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ struct stroke_interface_t {
|
|||||||
/**
|
/**
|
||||||
* @brief Create the stroke interface and listen on the socket.
|
* @brief Create the stroke interface and listen on the socket.
|
||||||
*
|
*
|
||||||
* @return stroke_t object
|
* @return interface_t for the stroke interface
|
||||||
*
|
*
|
||||||
* @ingroup interfaces
|
* @ingroup interfaces
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -59,5 +59,5 @@ interface_t *interface_create()
|
|||||||
|
|
||||||
this->public.interface.destroy = (void (*)(xml_interface_t*))destroy;
|
this->public.interface.destroy = (void (*)(xml_interface_t*))destroy;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public.interface;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-5
@@ -23,6 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/capability.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -178,7 +180,6 @@ static void destroy(private_daemon_t *this)
|
|||||||
DESTROY_IF(this->public.event_queue);
|
DESTROY_IF(this->public.event_queue);
|
||||||
DESTROY_IF(this->public.credentials);
|
DESTROY_IF(this->public.credentials);
|
||||||
DESTROY_IF(this->public.backends);
|
DESTROY_IF(this->public.backends);
|
||||||
sched_yield();
|
|
||||||
/* we hope the sender could send the outstanding deletes, but
|
/* we hope the sender could send the outstanding deletes, but
|
||||||
* we shut down here at any cost */
|
* we shut down here at any cost */
|
||||||
DESTROY_IF(this->public.sender);
|
DESTROY_IF(this->public.sender);
|
||||||
@@ -192,6 +193,7 @@ static void destroy(private_daemon_t *this)
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enforce daemon shutdown, with a given reason to do so.
|
* Enforce daemon shutdown, with a given reason to do so.
|
||||||
*/
|
*/
|
||||||
@@ -215,6 +217,39 @@ static void kill_daemon(private_daemon_t *this, char *reason)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop daemon capabilities
|
||||||
|
*/
|
||||||
|
static void drop_capabilities(private_daemon_t *this, bool netlink, bool bind)
|
||||||
|
{
|
||||||
|
struct __user_cap_header_struct hdr;
|
||||||
|
struct __user_cap_data_struct data;
|
||||||
|
u_int32_t keep = 0;
|
||||||
|
|
||||||
|
if (netlink)
|
||||||
|
{
|
||||||
|
/* CAP_NET_ADMIN is needed to use netlink */
|
||||||
|
keep |= (1<<CAP_NET_ADMIN);
|
||||||
|
}
|
||||||
|
if (bind)
|
||||||
|
{
|
||||||
|
/* CAP_NET_BIND_SERVICE to bind services below port 1024,
|
||||||
|
* CAP_NET_RAW to create RAW sockets. */
|
||||||
|
keep |= (1<<CAP_NET_BIND_SERVICE);
|
||||||
|
keep |= (1<<CAP_NET_RAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr.version = _LINUX_CAPABILITY_VERSION;
|
||||||
|
hdr.pid = 0;
|
||||||
|
data.effective = data.permitted = keep;
|
||||||
|
data.inheritable = 0;
|
||||||
|
|
||||||
|
if (capset(&hdr, &data))
|
||||||
|
{
|
||||||
|
kill_daemon(this, "unable to drop threads capabilities");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the daemon, optional with a strict crl policy
|
* Initialize the daemon, optional with a strict crl policy
|
||||||
*/
|
*/
|
||||||
@@ -240,13 +275,10 @@ static void initialize(private_daemon_t *this, bool syslog, level_t levels[])
|
|||||||
|
|
||||||
/* apply loglevels */
|
/* apply loglevels */
|
||||||
for (signal = 0; signal < DBG_MAX; signal++)
|
for (signal = 0; signal < DBG_MAX; signal++)
|
||||||
{
|
|
||||||
if (syslog)
|
|
||||||
{
|
{
|
||||||
this->public.syslog->set_level(this->public.syslog,
|
this->public.syslog->set_level(this->public.syslog,
|
||||||
signal, levels[signal]);
|
signal, levels[signal]);
|
||||||
}
|
if (!syslog)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
this->public.outlog->set_level(this->public.outlog,
|
this->public.outlog->set_level(this->public.outlog,
|
||||||
signal, levels[signal]);
|
signal, levels[signal]);
|
||||||
@@ -323,6 +355,7 @@ private_daemon_t *daemon_create(void)
|
|||||||
|
|
||||||
/* assign methods */
|
/* assign methods */
|
||||||
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
|
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
|
||||||
|
this->public.drop_capabilities = (void(*)(daemon_t*,bool,bool))drop_capabilities;
|
||||||
|
|
||||||
/* NULL members for clean destruction */
|
/* NULL members for clean destruction */
|
||||||
this->public.socket = NULL;
|
this->public.socket = NULL;
|
||||||
@@ -406,6 +439,9 @@ int main(int argc, char *argv[])
|
|||||||
level_t levels[DBG_MAX];
|
level_t levels[DBG_MAX];
|
||||||
int signal;
|
int signal;
|
||||||
|
|
||||||
|
/* keep bind() and netlink capabilities */
|
||||||
|
drop_capabilities(NULL, TRUE, TRUE);
|
||||||
|
|
||||||
/* use CTRL loglevel for default */
|
/* use CTRL loglevel for default */
|
||||||
for (signal = 0; signal < DBG_MAX; signal++)
|
for (signal = 0; signal < DBG_MAX; signal++)
|
||||||
{
|
{
|
||||||
@@ -480,6 +516,9 @@ int main(int argc, char *argv[])
|
|||||||
/* initialize daemon */
|
/* initialize daemon */
|
||||||
initialize(private_charon, use_syslog, levels);
|
initialize(private_charon, use_syslog, levels);
|
||||||
|
|
||||||
|
/* drop bind() capability, netlink is needed for cleanup */
|
||||||
|
drop_capabilities(private_charon, TRUE, FALSE);
|
||||||
|
|
||||||
/* load pluggable EAP modules */
|
/* load pluggable EAP modules */
|
||||||
eap_method_load(eapdir);
|
eap_method_load(eapdir);
|
||||||
|
|
||||||
|
|||||||
@@ -332,6 +332,8 @@ typedef struct daemon_t daemon_t;
|
|||||||
*/
|
*/
|
||||||
#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
|
#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
|
||||||
|
|
||||||
|
#define IPSEC_USER "nobody"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Main class of daemon, contains some globals.
|
* @brief Main class of daemon, contains some globals.
|
||||||
*
|
*
|
||||||
@@ -418,6 +420,15 @@ struct daemon_t {
|
|||||||
*/
|
*/
|
||||||
interface_manager_t *interfaces;
|
interface_manager_t *interfaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Let the calling thread drop its capabilities.
|
||||||
|
*
|
||||||
|
* @param this calling daemon
|
||||||
|
* @param netlink TRUE to keep CAP_NET_ADMIN (using netlink)
|
||||||
|
* @param bind TRUE to keep CAP_NET_BIND_SERVICE and CAP_NET_RAW
|
||||||
|
*/
|
||||||
|
void (*drop_capabilities) (daemon_t *this, bool netlink, bool bind);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shut down the daemon.
|
* @brief Shut down the daemon.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -172,6 +172,9 @@ struct route_entry_t {
|
|||||||
/** Source ip of the route */
|
/** Source ip of the route */
|
||||||
host_t *src_ip;
|
host_t *src_ip;
|
||||||
|
|
||||||
|
/** gateway for this route */
|
||||||
|
host_t *gateway;
|
||||||
|
|
||||||
/** Destination net */
|
/** Destination net */
|
||||||
chunk_t dst_net;
|
chunk_t dst_net;
|
||||||
|
|
||||||
@@ -185,6 +188,7 @@ struct route_entry_t {
|
|||||||
static void route_entry_destroy(route_entry_t *this)
|
static void route_entry_destroy(route_entry_t *this)
|
||||||
{
|
{
|
||||||
this->src_ip->destroy(this->src_ip);
|
this->src_ip->destroy(this->src_ip);
|
||||||
|
this->gateway->destroy(this->gateway);
|
||||||
chunk_free(&this->dst_net);
|
chunk_free(&this->dst_net);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -442,6 +446,9 @@ static void add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data,
|
|||||||
*/
|
*/
|
||||||
static void receive_events(private_kernel_interface_t *this)
|
static void receive_events(private_kernel_interface_t *this)
|
||||||
{
|
{
|
||||||
|
/* keep netlink capabilities only */
|
||||||
|
charon->drop_capabilities(charon, TRUE, FALSE);
|
||||||
|
|
||||||
while(TRUE)
|
while(TRUE)
|
||||||
{
|
{
|
||||||
unsigned char response[512];
|
unsigned char response[512];
|
||||||
@@ -1023,6 +1030,8 @@ static status_t manage_srcroute(private_kernel_interface_t *this, int nlmsg_type
|
|||||||
add_attribute(hdr, RTA_DST, route->dst_net, sizeof(request));
|
add_attribute(hdr, RTA_DST, route->dst_net, sizeof(request));
|
||||||
chunk = route->src_ip->get_address(route->src_ip);
|
chunk = route->src_ip->get_address(route->src_ip);
|
||||||
add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
|
add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
|
||||||
|
chunk = route->gateway->get_address(route->gateway);
|
||||||
|
add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request));
|
||||||
chunk.ptr = (char*)&route->if_index;
|
chunk.ptr = (char*)&route->if_index;
|
||||||
chunk.len = sizeof(route->if_index);
|
chunk.len = sizeof(route->if_index);
|
||||||
add_attribute(hdr, RTA_OIF, chunk, sizeof(request));
|
add_attribute(hdr, RTA_OIF, chunk, sizeof(request));
|
||||||
@@ -1689,6 +1698,8 @@ static status_t add_policy(private_kernel_interface_t *this,
|
|||||||
policy->route = malloc_thing(route_entry_t);
|
policy->route = malloc_thing(route_entry_t);
|
||||||
if (get_address_by_ts(this, dst_ts, &policy->route->src_ip) == SUCCESS)
|
if (get_address_by_ts(this, dst_ts, &policy->route->src_ip) == SUCCESS)
|
||||||
{
|
{
|
||||||
|
policy->route->gateway = (direction == POLICY_IN) ?
|
||||||
|
dst->clone(dst) : src->clone(src);
|
||||||
policy->route->if_index = get_interface_index(this, dst);
|
policy->route->if_index = get_interface_index(this, dst);
|
||||||
policy->route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16);
|
policy->route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16);
|
||||||
memcpy(policy->route->dst_net.ptr, &policy->sel.saddr, policy->route->dst_net.len);
|
memcpy(policy->route->dst_net.ptr, &policy->sel.saddr, policy->route->dst_net.len);
|
||||||
|
|||||||
@@ -254,6 +254,9 @@ static void receive_packets(private_receiver_t *this)
|
|||||||
DBG1(DBG_NET, "receiver thread running, thread_ID: %06u",
|
DBG1(DBG_NET, "receiver thread running, thread_ID: %06u",
|
||||||
(int)pthread_self());
|
(int)pthread_self());
|
||||||
|
|
||||||
|
/* drop threads capabilities */
|
||||||
|
charon->drop_capabilities(charon, FALSE, FALSE);
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* read in a packet */
|
/* read in a packet */
|
||||||
|
|||||||
@@ -84,11 +84,13 @@ static void send_(private_sender_t *this, packet_t *packet)
|
|||||||
*/
|
*/
|
||||||
static void send_packets(private_sender_t * this)
|
static void send_packets(private_sender_t * this)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* cancellation disabled by default */
|
/* cancellation disabled by default */
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
DBG1(DBG_NET, "sender thread running, thread_ID: %06u", (int)pthread_self());
|
DBG1(DBG_NET, "sender thread running, thread_ID: %06u", (int)pthread_self());
|
||||||
|
|
||||||
|
/* drop threads capabilities */
|
||||||
|
charon->drop_capabilities(charon, FALSE, FALSE);
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
packet_t *packet;
|
packet_t *packet;
|
||||||
@@ -119,9 +121,14 @@ static void send_packets(private_sender_t * this)
|
|||||||
*/
|
*/
|
||||||
static void destroy(private_sender_t *this)
|
static void destroy(private_sender_t *this)
|
||||||
{
|
{
|
||||||
|
/* send all packets in the queue */
|
||||||
|
while (this->list->get_count(this->list))
|
||||||
|
{
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
pthread_cancel(this->assigned_thread);
|
pthread_cancel(this->assigned_thread);
|
||||||
pthread_join(this->assigned_thread, NULL);
|
pthread_join(this->assigned_thread, NULL);
|
||||||
this->list->destroy_offset(this->list, offsetof(packet_t, destroy));
|
this->list->destroy(this->list);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ static void get_events(private_scheduler_t * this)
|
|||||||
DBG1(DBG_JOB, "scheduler thread running, thread_ID: %06u",
|
DBG1(DBG_JOB, "scheduler thread running, thread_ID: %06u",
|
||||||
(int)pthread_self());
|
(int)pthread_self());
|
||||||
|
|
||||||
|
/* drop threads capabilities */
|
||||||
|
charon->drop_capabilities(charon, FALSE, FALSE);
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
DBG2(DBG_JOB, "waiting for next event...");
|
DBG2(DBG_JOB, "waiting for next event...");
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ struct private_thread_pool_t {
|
|||||||
* Array of thread ids.
|
* Array of thread ids.
|
||||||
*/
|
*/
|
||||||
pthread_t *threads;
|
pthread_t *threads;
|
||||||
} ;
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of private_thread_pool_t.process_jobs.
|
* Implementation of private_thread_pool_t.process_jobs.
|
||||||
@@ -73,6 +73,9 @@ static void process_jobs(private_thread_pool_t *this)
|
|||||||
DBG1(DBG_JOB, "worker thread running, thread_ID: %06u",
|
DBG1(DBG_JOB, "worker thread running, thread_ID: %06u",
|
||||||
(int)pthread_self());
|
(int)pthread_self());
|
||||||
|
|
||||||
|
/* drop threads capabilities, except CAP_NET_ADMIN */
|
||||||
|
charon->drop_capabilities(charon, TRUE, FALSE);
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* TODO: should be atomic, but is not mission critical */
|
/* TODO: should be atomic, but is not mission critical */
|
||||||
|
|||||||
Reference in New Issue
Block a user