Teach key_expire() send SADB_EXPIRE message with the SADB_EXT_LIFETIME_HARD
extension header type. The key_flush_sad() now will send SADB_EXPIRE message when HARD lifetime expires. This is required by RFC 2367 and some keying daemons rely on these messages. HARD lifetime messages have precedence over SOFT lifetime messages, so now they will be checked first. Also now SADB_EXPIRE messages will be send even the SA has not been used, because keying daemons might want to rekey such SA. PR: 200282, 200283 Submitted by: Tobias Brunner <tobias at strongswan dot org> MFC after: 2 weeks
This commit is contained in:
parent
d395135696
commit
664802113f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=283101
@ -537,7 +537,7 @@ static int key_acquire2(struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *);
|
||||
static int key_register(struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *);
|
||||
static int key_expire(struct secasvar *);
|
||||
static int key_expire(struct secasvar *, int);
|
||||
static int key_flush(struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *);
|
||||
static int key_dump(struct socket *, struct mbuf *,
|
||||
@ -4242,41 +4242,29 @@ key_flush_sad(time_t now)
|
||||
"time, why?\n", __func__));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check SOFT lifetime */
|
||||
if (sav->lft_s->addtime != 0 &&
|
||||
now - sav->created > sav->lft_s->addtime) {
|
||||
key_sa_chgstate(sav, SADB_SASTATE_DYING);
|
||||
/*
|
||||
* Actually, only send expire message if
|
||||
* SA has been used, as it was done before,
|
||||
* but should we always send such message,
|
||||
* and let IKE daemon decide if it should be
|
||||
* renegotiated or not ?
|
||||
* XXX expire message will actually NOT be
|
||||
* sent if SA is only used after soft
|
||||
* lifetime has been reached, see below
|
||||
* (DYING state)
|
||||
*/
|
||||
if (sav->lft_c->usetime != 0)
|
||||
key_expire(sav);
|
||||
}
|
||||
/* check SOFT lifetime by bytes */
|
||||
/*
|
||||
* XXX I don't know the way to delete this SA
|
||||
* when new SA is installed. Caution when it's
|
||||
* installed too big lifetime by time.
|
||||
* RFC 2367:
|
||||
* HARD lifetimes MUST take precedence over SOFT
|
||||
* lifetimes, meaning if the HARD and SOFT lifetimes
|
||||
* are the same, the HARD lifetime will appear on the
|
||||
* EXPIRE message.
|
||||
*/
|
||||
else if (sav->lft_s->bytes != 0 &&
|
||||
sav->lft_s->bytes < sav->lft_c->bytes) {
|
||||
|
||||
/* check HARD lifetime */
|
||||
if ((sav->lft_h->addtime != 0 &&
|
||||
now - sav->created > sav->lft_h->addtime) ||
|
||||
(sav->lft_h->bytes != 0 &&
|
||||
sav->lft_h->bytes < sav->lft_c->bytes)) {
|
||||
key_sa_chgstate(sav, SADB_SASTATE_DEAD);
|
||||
key_expire(sav, 1);
|
||||
KEY_FREESAV(&sav);
|
||||
}
|
||||
/* check SOFT lifetime */
|
||||
else if ((sav->lft_s->addtime != 0 &&
|
||||
now - sav->created > sav->lft_s->addtime) ||
|
||||
(sav->lft_s->bytes != 0 &&
|
||||
sav->lft_s->bytes < sav->lft_c->bytes)) {
|
||||
key_sa_chgstate(sav, SADB_SASTATE_DYING);
|
||||
/*
|
||||
* XXX If we keep to send expire
|
||||
* message in the status of
|
||||
* DYING. Do remove below code.
|
||||
*/
|
||||
key_expire(sav);
|
||||
key_expire(sav, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4295,6 +4283,7 @@ key_flush_sad(time_t now)
|
||||
|
||||
if (sav->lft_h->addtime != 0 &&
|
||||
now - sav->created > sav->lft_h->addtime) {
|
||||
key_expire(sav, 1);
|
||||
key_sa_chgstate(sav, SADB_SASTATE_DEAD);
|
||||
KEY_FREESAV(&sav);
|
||||
}
|
||||
@ -4311,12 +4300,13 @@ key_flush_sad(time_t now)
|
||||
* If there is no SA then sending
|
||||
* expire message.
|
||||
*/
|
||||
key_expire(sav);
|
||||
key_expire(sav, 0);
|
||||
}
|
||||
#endif
|
||||
/* check HARD lifetime by bytes */
|
||||
else if (sav->lft_h->bytes != 0 &&
|
||||
sav->lft_h->bytes < sav->lft_c->bytes) {
|
||||
key_expire(sav, 1);
|
||||
key_sa_chgstate(sav, SADB_SASTATE_DEAD);
|
||||
KEY_FREESAV(&sav);
|
||||
}
|
||||
@ -6721,7 +6711,7 @@ key_freereg(struct socket *so)
|
||||
* others : error number
|
||||
*/
|
||||
static int
|
||||
key_expire(struct secasvar *sav)
|
||||
key_expire(struct secasvar *sav, int hard)
|
||||
{
|
||||
int satype;
|
||||
struct mbuf *result = NULL, *m;
|
||||
@ -6779,11 +6769,19 @@ key_expire(struct secasvar *sav)
|
||||
lt->sadb_lifetime_usetime = sav->lft_c->usetime;
|
||||
lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2);
|
||||
lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
|
||||
lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
|
||||
lt->sadb_lifetime_allocations = sav->lft_s->allocations;
|
||||
lt->sadb_lifetime_bytes = sav->lft_s->bytes;
|
||||
lt->sadb_lifetime_addtime = sav->lft_s->addtime;
|
||||
lt->sadb_lifetime_usetime = sav->lft_s->usetime;
|
||||
if (hard) {
|
||||
lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
|
||||
lt->sadb_lifetime_allocations = sav->lft_h->allocations;
|
||||
lt->sadb_lifetime_bytes = sav->lft_h->bytes;
|
||||
lt->sadb_lifetime_addtime = sav->lft_h->addtime;
|
||||
lt->sadb_lifetime_usetime = sav->lft_h->usetime;
|
||||
} else {
|
||||
lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
|
||||
lt->sadb_lifetime_allocations = sav->lft_s->allocations;
|
||||
lt->sadb_lifetime_bytes = sav->lft_s->bytes;
|
||||
lt->sadb_lifetime_addtime = sav->lft_s->addtime;
|
||||
lt->sadb_lifetime_usetime = sav->lft_s->usetime;
|
||||
}
|
||||
m_cat(result, m);
|
||||
|
||||
/* set sadb_address for source */
|
||||
|
Loading…
Reference in New Issue
Block a user