applied new changes from NATT team

DPD only done when no IPsec and IKE traffic processed
	minor changes here and there
This commit is contained in:
Martin Willi
2006-06-23 14:02:30 +00:00
parent 2891590b05
commit 2f89902d07
20 changed files with 358 additions and 226 deletions
-15
View File
@@ -55,12 +55,6 @@
*/
#define KEEPALIVE_INTERVAL 2000000
/**
* Keepalive timeout in milliseconds.
* Not implemented yet.
*/
#define KEEPALIVE_TIMEOUT 30000000
/**
* DPD interval in milliseconds.
*/
@@ -112,14 +106,6 @@ static u_int32_t get_keepalive_interval (private_configuration_t *this)
return KEEPALIVE_INTERVAL;
}
/**
* Implementation of configuration_t.get_keepalive_timeout.
*/
static u_int32_t get_keepalive_timeout (private_configuration_t *this)
{
return KEEPALIVE_TIMEOUT;
}
/**
* Implementation of configuration_t.get_dpd_interval.
*/
@@ -148,7 +134,6 @@ configuration_t *configuration_create()
this->public.get_retransmit_timeout = (status_t (*) (configuration_t *, u_int32_t retransmit_count, u_int32_t *timeout))get_retransmit_timeout;
this->public.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_t *)) get_half_open_ike_sa_timeout;
this->public.get_keepalive_interval = (u_int32_t (*) (configuration_t *)) get_keepalive_interval;
this->public.get_keepalive_timeout = (u_int32_t (*) (configuration_t *)) get_keepalive_timeout;
this->public.get_dpd_interval = (u_int32_t (*) (configuration_t *)) get_dpd_interval;
return (&this->public);
-11
View File
@@ -80,17 +80,6 @@ struct configuration_t {
*/
u_int32_t (*get_keepalive_interval) (configuration_t *this);
/**
* @brief Returns the keepalive timeout in ms.
*
* The keepalive timeout defines how long we should keep sending
* NAT keepalives after closing an IKE_SA.
*
* @param this calling object
* @return timeout in milliseconds (ms)
*/
u_int32_t (*get_keepalive_timeout) (configuration_t *this);
/**
* @brief Returns the DPD interval in ms.
*
+1 -1
View File
@@ -22,7 +22,7 @@
#include <string.h>
#include "connection.h"
#include <config/connections/connection.h>
#include <utils/linked_list.h>
#include <utils/logger.h>
+1
View File
@@ -273,6 +273,7 @@ struct daemon_t {
* A socket_t instance.
*/
socket_t *socket;
/**
* A interfaces_t instance.
*/
+1
View File
@@ -147,6 +147,7 @@ interfaces_t *interfaces_create(u_int16_t port)
if (initialize(this) != SUCCESS)
{
destroy(this);
return NULL;
}
return &this->public;
+2 -2
View File
@@ -395,9 +395,9 @@ static status_t initialize(private_socket_t *this)
int type = UDP_ENCAP_ESPINUDP;
if (setsockopt(this->natt_fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
this->logger->log(this->logger, ERROR,
this->logger->log(this->logger, ERROR,
"unable to set UDP_ENCAP on natt send socket! NAT-T may fail! error: %s",
strerror(errno));
strerror(errno));
}
}
+23 -3
View File
@@ -66,6 +66,9 @@ static status_t execute(private_send_dpd_job_t *this)
{
ike_sa_t *ike_sa;
status_t status;
u_int32_t dt;
u_int32_t interval = charon->configuration->get_dpd_interval(charon->configuration);
struct timeval last_msg_tv, current_tv;
this->logger->log(this->logger, CONTROL|LEVEL2, "Checking out IKE SA %lld:%lld, role %s",
this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
@@ -81,9 +84,26 @@ static status_t execute(private_send_dpd_job_t *this)
return DESTROY_ME;
}
ike_sa->send_dpd_request(ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL1,
"DPD request packet scheduled");
last_msg_tv = ike_sa->get_last_traffic_in_tv(ike_sa);
if (0 > gettimeofday(&current_tv, NULL) )
{
this->logger->log(this->logger, ERROR|LEVEL1,
"Warning: Failed to get time of day.");
}
dt = (current_tv.tv_sec - last_msg_tv.tv_sec) * 1000
+ (current_tv.tv_usec - last_msg_tv.tv_usec) / 1000;
if (dt >= interval)
{
ike_sa->send_dpd_request(ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL1,
"DPD request packet scheduled");
}
else
{
charon->event_queue->add_relative(charon->event_queue, (job_t*) this, interval - dt);
}
this->logger->log(this->logger, CONTROL|LEVEL2,
"Checkin IKE SA %lld:%lld, role %s",
+2 -4
View File
@@ -68,7 +68,6 @@ static status_t execute(private_send_keepalive_job_t *this)
status_t status;
u_int32_t dt;
u_int32_t interval = charon->configuration->get_keepalive_interval(charon->configuration);
u_int32_t timeout = charon->configuration->get_keepalive_timeout(charon->configuration);
struct timeval last_msg_tv, current_tv;
packet_t *packet;
host_t *host;
@@ -89,7 +88,7 @@ static status_t execute(private_send_keepalive_job_t *this)
return DESTROY_ME;
}
last_msg_tv = ike_sa->get_last_msg_tv(ike_sa);
last_msg_tv = ike_sa->get_last_traffic_out_tv(ike_sa);
if (0 > gettimeofday(&current_tv, NULL) )
{
this->logger->log(this->logger, ERROR|LEVEL1,
@@ -114,8 +113,7 @@ static status_t execute(private_send_keepalive_job_t *this)
this->logger->log(this->logger, CONTROL|LEVEL1,
"NAT keepalive packet scheduled");
}
charon->event_queue->add_relative(charon->event_queue,
(job_t*) this, interval - dt);
charon->event_queue->add_relative(charon->event_queue, (job_t*) this, interval - dt);
this->logger->log(this->logger, CONTROL|LEVEL2,
"Checkin IKE SA %lld:%lld, role %s",
+89 -1
View File
@@ -327,7 +327,6 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
static status_t add(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus)
{
linked_list_t *list;
u_int32_t outbound_spi, inbound_spi;
/* backup outbound spi, as alloc overwrites it */
@@ -539,6 +538,94 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
iterator->destroy(iterator);
}
/**
* Implementation of child_sa_t.get_use_time
*/
static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use_time)
{
iterator_t *iterator;
sa_policy_t *policy;
struct protoent *proto;
char proto_buf[8] = "";
char *proto_name = proto_buf;
status_t status;
*use_time = UNDEFINED_TIME;
iterator = this->policies->create_iterator(this->policies, TRUE);
while (iterator->iterate(iterator, (void**)&policy))
{
time_t ut;
if (policy->upper_proto)
{
proto = getprotobynumber(policy->upper_proto);
if (proto)
{
proto_name = proto->p_name;
}
else
{
snprintf(proto_buf, sizeof(proto_buf), "<%d>", policy->upper_proto);
}
}
this->logger->log(this->logger, CONTROL|LEVEL1,
"quering policy: %s/%d==%s==%s/%d",
policy->me.net->get_address(policy->me.net), policy->me.net_mask,
proto_name,
policy->other.net->get_address(policy->other.net), policy->other.net_mask);
if (inbound)
{
status = charon->kernel_interface->query_policy(charon->kernel_interface,
this->other.addr, this->me.addr,
policy->other.net, policy->me.net,
policy->other.net_mask, policy->me.net_mask,
XFRM_POLICY_IN, policy->upper_proto,
&ut);
/* also check forward policy in tunnel mode */
if (status == SUCCESS /*&& mode == TUNNEL XXX */)
{
time_t fwd;
status = charon->kernel_interface->query_policy(charon->kernel_interface,
this->other.addr, this->me.addr,
policy->other.net, policy->me.net,
policy->other.net_mask, policy->me.net_mask,
XFRM_POLICY_FWD, policy->upper_proto,
&fwd);
if (status == SUCCESS)
{
ut = max(ut, fwd);
}
}
}
else
{
status = charon->kernel_interface->query_policy(charon->kernel_interface,
this->me.addr, this->other.addr,
policy->me.net, policy->other.net,
policy->me.net_mask, policy->other.net_mask,
XFRM_POLICY_OUT, policy->upper_proto,
&ut);
}
if (status != SUCCESS)
{
iterator->destroy(iterator);
return FAILED;
}
*use_time = max(*use_time, ut);
}
iterator->destroy(iterator);
return SUCCESS;
}
/**
* Update the host adress/port of a SA
*/
@@ -772,6 +859,7 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))add;
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))update;
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies;
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
this->public.set_rekeyed = (void (*)(child_sa_t*))set_rekeyed;
this->public.log_status = (void (*)(child_sa_t*, logger_t*, char*))log_status;
this->public.destroy = (void(*)(child_sa_t*))destroy;
+10
View File
@@ -157,6 +157,16 @@ struct child_sa_t {
*/
status_t (*add_policies) (child_sa_t *this, linked_list_t *my_ts_list, linked_list_t *other_ts_list);
/**
* @brief Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
*
* @param this calling object
* @param inbound query for in- or outbound usage
* @param use_time the time
* @return SUCCESS or FAILED
*/
status_t (*get_use_time) (child_sa_t *this, bool inbound, time_t *use_time);
/**
* @brief Mark this child_sa as rekeyed.
*
+95 -20
View File
@@ -67,6 +67,16 @@ struct private_ike_sa_t {
*/
protected_ike_sa_t protected;
/**
* Update a timestamp on ike traffic
*/
void (*update_timestamp)(private_ike_sa_t *this, bool in);
/**
* Returns the time since last traffic on kernel policies
*/
struct timeval (*get_last_esp_traffic_tv)(private_ike_sa_t * this, bool inbound);
/**
* Identifier for the current IKE_SA.
*/
@@ -194,9 +204,14 @@ struct private_ike_sa_t {
bool nat_there;
/**
* Timestamp of last IKE message sent or received on this SA
* Timestamp of last IKE message received on this SA
*/
struct timeval last_msg_tv;
struct timeval last_msg_in_tv;
/**
* Timestamp of last IKE message sent on this SA
*/
struct timeval last_msg_out_tv;
/*
* Message ID of last DPD message
@@ -330,7 +345,7 @@ static host_t* get_my_host(private_ike_sa_t *this)
*/
static host_t* get_other_host(private_ike_sa_t *this)
{
return this->connection->get_other_host(this->connection);;
return this->connection->get_other_host(this->connection);
}
/**
@@ -338,7 +353,7 @@ static host_t* get_other_host(private_ike_sa_t *this)
*/
static identification_t* get_my_id(private_ike_sa_t *this)
{
return this->policy->get_my_id(this->policy);;
return this->policy->get_my_id(this->policy);
}
/**
@@ -346,7 +361,7 @@ static identification_t* get_my_id(private_ike_sa_t *this)
*/
static identification_t* get_other_id(private_ike_sa_t *this)
{
return this->policy->get_other_id(this->policy);;
return this->policy->get_other_id(this->policy);
}
/**
@@ -375,7 +390,7 @@ static status_t retransmit_request(private_ike_sa_t *this, u_int32_t message_id)
this->logger->log(this->logger, CONTROL | LEVEL1, "Going to retransmit message with id %d",message_id);
packet = this->last_requested_message->get_packet(this->last_requested_message);
charon->send_queue->add(charon->send_queue, packet);
this->update_timestamp(this, FALSE);
return SUCCESS;
}
@@ -606,6 +621,20 @@ static signer_t *get_signer_responder(private_ike_sa_t *this)
return this->signer_responder;
}
/**
* Implementation of protected_ike_sa_t.update_timestamp
*/
static void update_timestamp(private_ike_sa_t *this, bool in)
{
/* bump last message sent timestamp */
struct timeval *tv = in ? &this->last_msg_in_tv : &this->last_msg_out_tv;
if (0 > gettimeofday(tv, NULL))
{
this->logger->log(this->logger, ERROR|LEVEL1,
"Warning: Failed to get time of day.");
}
}
/**
* Implementation of protected_ike_sa_t.send_request.
*/
@@ -678,11 +707,7 @@ static status_t send_request(private_ike_sa_t *this, message_t *message)
this->message_id_out);
this->message_id_out++;
/* bump last message sent timestamp */
if (gettimeofday(&this->last_msg_tv, NULL) < 0)
{
this->logger->log(this->logger, ERROR|LEVEL1, "failed to get time of day");
}
this->update_timestamp(this, FALSE);
return SUCCESS;
}
@@ -740,6 +765,8 @@ static status_t send_response(private_ike_sa_t *this, message_t *message)
this->logger->log(this->logger, CONTROL|LEVEL3, "Increase message counter for incoming messages");
this->message_id_in++;
this->update_timestamp(this, FALSE);
return SUCCESS;
}
@@ -780,6 +807,8 @@ static void send_notify(private_ike_sa_t *this, exchange_type_t exchange_type, n
charon->send_queue->add(charon->send_queue, packet);
this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy message");
response->destroy(response);
this->update_timestamp(this, FALSE);
}
/**
@@ -842,6 +871,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
packet_t *packet = this->last_responded_message->get_packet(this->last_responded_message);
this->logger->log(this->logger, CONTROL|LEVEL1, "Resent request detected. Send stored reply.");
charon->send_queue->add(charon->send_queue, packet);
this->update_timestamp(this, FALSE);
return SUCCESS;
}
else
@@ -875,6 +905,8 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
}
}
this->update_timestamp(this, TRUE);
/* now the message is processed by the current state object.
* The specific state object is responsible to check if a message can be received in
* the state it represents.
@@ -1412,14 +1444,50 @@ static void set_other_host_behind_nat (private_ike_sa_t *this, bool nat)
}
/**
* Implementation of ike_sa_t.get_last_msg_tv.
* Implementation of private_ike_sa_t.get_last_esp_traffic_tv
*/
static struct timeval get_last_msg_tv (private_ike_sa_t *this)
static struct timeval get_last_esp_traffic_tv(private_ike_sa_t * this, bool inbound)
{
/*
* XXX: query kernel for last activity time
*/
return this->last_msg_tv;
iterator_t *iterator;
child_sa_t *child_sa;
bool ret = TRUE;
time_t use_time = 0;
struct timeval tv = {0, 0};
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->iterate(iterator, (void**)&child_sa))
{
if (child_sa->get_use_time(child_sa, inbound, &use_time) == SUCCESS
&& use_time != 0)
{
tv.tv_sec = max(tv.tv_sec, use_time);
}
}
iterator->destroy(iterator);
return tv;
}
/**
* Implementation of ike_sa_t.get_last_traffic_in_tv.
*/
static struct timeval get_last_traffic_in_tv (private_ike_sa_t *this)
{
struct timeval esp_tv = this->get_last_esp_traffic_tv(this, TRUE);
return this->last_msg_in_tv.tv_sec > esp_tv.tv_sec ? this->last_msg_in_tv
: this->last_msg_in_tv.tv_sec < esp_tv.tv_sec ? esp_tv
: this->last_msg_in_tv.tv_usec > esp_tv.tv_usec ? this->last_msg_in_tv : esp_tv;
}
/**
* Implementation of ike_sa_t.get_last_traffic_out_tv.
*/
static struct timeval get_last_traffic_out_tv (private_ike_sa_t *this)
{
struct timeval esp_tv = this->get_last_esp_traffic_tv(this, FALSE);
return this->last_msg_out_tv.tv_sec > esp_tv.tv_sec ? this->last_msg_out_tv
: this->last_msg_out_tv.tv_sec < esp_tv.tv_sec ? esp_tv
: this->last_msg_out_tv.tv_usec > esp_tv.tv_usec ? this->last_msg_out_tv : esp_tv;
}
/**
@@ -1543,7 +1611,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->protected.public.is_my_host_behind_nat = (bool(*)(ike_sa_t*)) is_my_host_behind_nat;
this->protected.public.is_other_host_behind_nat = (bool(*)(ike_sa_t*)) is_other_host_behind_nat;
this->protected.public.is_any_host_behind_nat = (bool(*)(ike_sa_t*)) is_any_host_behind_nat;
this->protected.public.get_last_msg_tv = (struct timeval (*)(ike_sa_t*)) get_last_msg_tv;
this->protected.public.get_last_traffic_in_tv = (struct timeval (*)(ike_sa_t*)) get_last_traffic_in_tv;
this->protected.public.get_last_traffic_out_tv = (struct timeval (*)(ike_sa_t*)) get_last_traffic_out_tv;
this->protected.public.send_dpd_request = (status_t (*)(ike_sa_t*)) send_dpd_request;
/* protected functions */
@@ -1579,6 +1648,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->protected.get_last_dpd_message_id = (u_int32_t (*) (protected_ike_sa_t*)) get_last_dpd_message_id;
this->protected.update_connection_hosts = (status_t (*) (protected_ike_sa_t *, host_t*, host_t*)) update_connection_hosts;
/* private functions */
this->update_timestamp = (void (*) (private_ike_sa_t*,bool))update_timestamp;
this->get_last_esp_traffic_tv = (struct timeval (*) (private_ike_sa_t *,bool))get_last_esp_traffic_tv;
/* initialize private fields */
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
@@ -1604,8 +1677,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->nat_hasher = hasher_create(HASH_SHA1);
this->nat_here = FALSE;
this->nat_there = FALSE;
this->last_msg_tv.tv_sec = 0;
this->last_msg_tv.tv_usec = 0;
this->last_msg_in_tv.tv_sec = 0;
this->last_msg_in_tv.tv_usec = 0;
this->last_msg_out_tv.tv_sec = 0;
this->last_msg_out_tv.tv_usec = 0;
this->last_dpd_message_id = 0;
/* at creation time, IKE_SA is in a initiator state */
+12 -4
View File
@@ -236,12 +236,20 @@ struct ike_sa_t {
bool (*is_any_host_behind_nat) (ike_sa_t *this);
/**
* @brief Query timeval of last message sent.
* @brief Query timeval of last inbound IKE or ESP traffic.
*
* @param this calling object
* @return time when the last message was sent
* @param this calling object
* @return time when the last traffic was seen
*/
struct timeval (*get_last_msg_tv) (ike_sa_t *this);
struct timeval (*get_last_traffic_in_tv) (ike_sa_t *this);
/**
* @brief Query timeval of last outbound IKE or ESP traffic.
*
* @param this calling object
* @return time when the last traffic was seen
*/
struct timeval (*get_last_traffic_out_tv) (ike_sa_t *this);
/**
* @brief Get the state of type of associated state object.
+23 -8
View File
@@ -554,14 +554,6 @@ static status_t process_message(private_ike_sa_established_t *this, message_t *m
signer_t *signer;
status_t status;
/* only requests are allowed, responses are handled in other state */
if (!message->get_request(message))
{
this->logger->log(this->logger, ERROR|LEVEL1,
"Response not handled in state ike_sa_established");
return FAILED;
}
/* get signer for verification and crypter for decryption */
ike_sa_id = this->ike_sa->public.get_id(&this->ike_sa->public);
if (!ike_sa_id->is_initiator(ike_sa_id))
@@ -590,6 +582,28 @@ static status_t process_message(private_ike_sa_established_t *this, message_t *m
{
return status;
}
/* process responses */
if (!message->get_request(message))
{
switch (message->get_exchange_type(message))
{
case INFORMATIONAL:
status = process_informational_response(this, message);
break;
default:
this->logger->log(this->logger, ERROR | LEVEL1,
"Only INFORMATIONAL responses are handled in state ike_sa_established");
status = FAILED;
break;
}
/* we don't really reply to this message but the retransmit mechanism relies on this */
this->ike_sa->set_last_replied_message_id(this->ike_sa, message->get_message_id(message));
/* return here */
return status;
}
/* prepare a reply of the same type */
this->ike_sa->build_message(this->ike_sa, message->get_exchange_type(message), FALSE, &response);
@@ -609,6 +623,7 @@ static status_t process_message(private_ike_sa_established_t *this, message_t *m
mapping_find(exchange_type_m, message->get_exchange_type(message)));
status = NOT_SUPPORTED;
}
return status;
}
+1
View File
@@ -94,6 +94,7 @@ struct private_initiator_init_t {
* @param request message_t object to add the NONCE payload
*/
status_t (*build_nonce_payload) (private_initiator_init_t *this,message_t *request);
/**
* Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
+2
View File
@@ -388,6 +388,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
response->destroy(response);
return status;
}
/* build Notify(NAT-D) payloads */
this->build_natd_payloads(this, response);
@@ -616,6 +617,7 @@ static status_t process_notify_payload(private_responder_init_t *this, notify_pa
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_message_type_m, notify_message_type));
switch (notify_message_type)
{
case NAT_DETECTION_DESTINATION_IP:
+70
View File
@@ -673,6 +673,75 @@ static status_t add_policy(private_kernel_interface_t *this,
return status;
}
static status_t query_policy(private_kernel_interface_t *this,
host_t *me, host_t *other,
host_t *src, host_t *dst,
u_int8_t src_hostbits, u_int8_t dst_hostbits,
int direction, int upper_proto,
time_t *use_time)
{
unsigned char request[BUFFER_SIZE];
struct nlmsghdr *response;
memset(&request, 0, sizeof(request));
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "querying policy");
struct nlmsghdr *hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETPOLICY;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
struct xfrm_userpolicy_id *policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
policy_id->sel.sport = htons(src->get_port(src));
policy_id->sel.sport_mask = (policy_id->sel.sport) ? ~0 : 0;
policy_id->sel.saddr = src->get_xfrm_addr(src);
policy_id->sel.prefixlen_s = src_hostbits;
policy_id->sel.dport = htons(dst->get_port(dst));
policy_id->sel.dport_mask = (policy_id->sel.dport) ? ~0 : 0;
policy_id->sel.daddr = dst->get_xfrm_addr(dst);
policy_id->sel.prefixlen_d = dst_hostbits;
policy_id->sel.proto = upper_proto;
policy_id->sel.family = src->get_family(src);
policy_id->dir = direction;
if (this->send_message(this, hdr, &response) != SUCCESS)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
return FAILED;
}
else if (response->nlmsg_type == NLMSG_ERROR)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
free(response);
return FAILED;
}
else if (response->nlmsg_type != XFRM_MSG_NEWPOLICY)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an unknown reply");
free(response);
return FAILED;
}
else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)))
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an invalid reply");
free(response);
return FAILED;
}
struct xfrm_userpolicy_info *policy = (struct xfrm_userpolicy_info*)NLMSG_DATA(response);
*use_time = (time_t)policy->curlft.use_time;
free(response);
return status;
}
/**
* Implementation of kernel_interface_t.del_policy.
*/
@@ -923,6 +992,7 @@ kernel_interface_t *kernel_interface_create()
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*, host_t*,host_t*,host_t*,u_int8_t,u_int8_t,int,int,protocol_id_t,u_int32_t))add_policy;
this->public.update_sa_hosts = (status_t(*)(kernel_interface_t*,host_t*,host_t*,host_t*,host_t*,int,int,u_int32_t,protocol_id_t))update_sa_hosts;
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
this->public.query_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,host_t*,host_t*,u_int8_t,u_int8_t,int,int,time_t*))query_policy;
this->public.del_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,host_t*,host_t*,u_int8_t,u_int8_t,int,int))del_policy;
this->public.destroy = (void(*)(kernel_interface_t*)) destroy;
+24
View File
@@ -118,6 +118,7 @@ struct kernel_interface_t {
prf_plus_t *prf_plus,
natt_conf_t *natt,
bool replace);
/**
* @brief Update the hosts on an installed SA. Encapsulation ports are also updated.
*
@@ -190,6 +191,29 @@ struct kernel_interface_t {
int direction, int upper_proto,
protocol_id_t protocol,
u_int32_t reqid);
/**
* @brief Query the use time of a policy
*
* @param this calling object
* @param me address of local peer
* @param other address of remote peer
* @param src src address of traffic this policy applies
* @param dst dest address of traffic this policy applies
* @param src_hostbits subnetmask to use for src address
* @param dst_hostbits subnetmask to use for dst address
* @param direction direction of traffic, XFRM_POLICY_OUT, XFRM_POLICY_IN, XFRM_POLICY_FWD
* @param upper_proto upper layer protocol of traffic for this policy (TCP, UDP, ICMP, ...)
* @param use_time the time of this policy's last use
* @return
* - SUCCESS
* - FAILED if kernel comm failed
*/
status_t (*query_policy) (kernel_interface_t *this,
host_t *me, host_t *other,
host_t *src, host_t *dst,
u_int8_t src_hostbits, u_int8_t dst_hostbits,
int direction, int upper_proto,
time_t *use_time);
/**
* @brief Remove a policy from the SPD.