diff options
author | Martin Willi <martin@revosec.ch> | 2013-04-21 17:05:08 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-05-06 17:01:13 +0200 |
commit | 5c12700f9abc5efeb38d18a46edf152894476e8c (patch) | |
tree | 6ce337b522191636323bbd7638238afed6ff736f /src/libhydra | |
parent | bdaf9f97e6cd3e97f4b947e8748efd5b34c4c72e (diff) | |
download | strongswan-5c12700f9abc5efeb38d18a46edf152894476e8c.tar.bz2 strongswan-5c12700f9abc5efeb38d18a46edf152894476e8c.tar.xz |
kernel-interface: query SAD for last use time if SPD query didn't yield one
Diffstat (limited to 'src/libhydra')
-rw-r--r-- | src/libhydra/kernel/kernel_interface.c | 4 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_interface.h | 3 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_ipsec.h | 3 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c | 2 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c | 8 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 16 |
6 files changed, 28 insertions, 8 deletions
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 290c25a62..d81fa33c7 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -208,14 +208,14 @@ METHOD(kernel_interface_t, update_sa, status_t, METHOD(kernel_interface_t, query_sa, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi, u_int8_t protocol, mark_t mark, - u_int64_t *bytes, u_int64_t *packets) + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time) { if (!this->ipsec) { return NOT_SUPPORTED; } return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark, - bytes, packets); + bytes, packets, time); } METHOD(kernel_interface_t, del_sa, status_t, diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index fd64f50c2..b333cae99 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -197,11 +197,12 @@ struct kernel_interface_t { * @param mark optional mark for this SA * @param[out] bytes the number of bytes processed by SA * @param[out] packets number of packets processed by SA + * @param[out] time last time of SA use * @return SUCCESS if operation completed */ status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi, u_int8_t protocol, mark_t mark, - u_int64_t *bytes, u_int64_t *packets); + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time); /** * Delete a previously installed SA from the SAD. diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h index ba67238e5..f61f3c3aa 100644 --- a/src/libhydra/kernel/kernel_ipsec.h +++ b/src/libhydra/kernel/kernel_ipsec.h @@ -155,11 +155,12 @@ struct kernel_ipsec_t { * @param mark optional mark for this SA * @param[out] bytes the number of bytes processed by SA * @param[out] packets number of packets processed by SA + * @param[out] time last time of SA use * @return SUCCESS if operation completed */ status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, u_int8_t protocol, mark_t mark, - u_int64_t *bytes, u_int64_t *packets); + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time); /** * Delete a previusly installed SA from the SAD. diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c index 2d09d33cc..32bea7383 100644 --- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c +++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c @@ -1911,7 +1911,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, METHOD(kernel_ipsec_t, query_sa, status_t, private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, u_int8_t protocol, mark_t mark, - u_int64_t *bytes, u_int64_t *packets) + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time) { return NOT_SUPPORTED; /* TODO */ } diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index b30c9533f..58bce6247 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -1595,7 +1595,7 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this, METHOD(kernel_ipsec_t, query_sa, status_t, private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, u_int8_t protocol, mark_t mark, - u_int64_t *bytes, u_int64_t *packets) + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time) { netlink_buf_t request; struct nlmsghdr *out = NULL, *hdr; @@ -1680,6 +1680,12 @@ METHOD(kernel_ipsec_t, query_sa, status_t, { *packets = sa->curlft.packets; } + if (time) + { /* curlft contains an "use" time, but that contains a timestamp + * of the first use, not the last. Last use time must be queried + * on the policy on Linux */ + *time = 0; + } status = SUCCESS; } memwipe(out, len); diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 3ade6f4a5..ecab2827a 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -1804,7 +1804,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, METHOD(kernel_ipsec_t, query_sa, status_t, private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, u_int8_t protocol, mark_t mark, - u_int64_t *bytes, u_int64_t *packets) + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time) { unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; @@ -1862,6 +1862,18 @@ METHOD(kernel_ipsec_t, query_sa, status_t, /* not supported by PF_KEY */ *packets = 0; } + if (time) + { +#ifdef __APPLE__ + /* OS X uses the "last" time of use in usetime */ + *time = response.lft_current->sadb_lifetime_usetime; +#else /* !__APPLE__ */ + /* on Linux, sadb_lifetime_usetime is set to the "first" time of use, + * which is actually correct according to PF_KEY. We have to query + * policies for the last usetime. */ + *time = 0; +#endif /* !__APPLE__ */ + } free(out); return SUCCESS; @@ -2435,7 +2447,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t, } else if (response.lft_current == NULL) { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " + DBG2(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " "use time", src_ts, dst_ts, policy_dir_names, direction); free(out); return FAILED; |