From: VANHULLEBUS Y. <va...@us...> - 2005-07-25 15:28:15
|
Update of /cvsroot/ipsec-tools/ipsec-tools/src/racoon In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11031/src/racoon Modified Files: isakmp.c Log Message: Do not purge IPSec SAs in purge_remote() if a new ph1handle exists Index: isakmp.c =================================================================== RCS file: /cvsroot/ipsec-tools/ipsec-tools/src/racoon/isakmp.c,v retrieving revision 1.58 retrieving revision 1.59 diff -u -d -r1.58 -r1.59 --- isakmp.c 19 Jul 2005 15:25:32 -0000 1.58 +++ isakmp.c 25 Jul 2005 15:28:07 -0000 1.59 @@ -3097,8 +3097,22 @@ struct sockaddr *src, *dst; caddr_t mhp[SADB_EXT_MAX + 1]; struct ph2handle *iph2; + struct ph1handle *new_iph1; - /* Delete all phase2 SAs */ + plog(LLV_INFO, LOCATION, NULL, + "purging ISAKMP-SA spi=%s.\n", + isakmp_pindex(&(iph1->index), iph1->msgid)); + + /* Mark as expired. */ + iph1->status = PHASE1ST_EXPIRED; + + /* Check if we have another, still valid, phase1 SA. */ + new_iph1 = getph1byaddr(iph1->local, iph1->remote); + + /* + * Delete all orphaned or binded to the deleting ph1handle phase2 SAs. + * Keep all others phase2 SAs. + */ buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); if (buf == NULL) { plog(LLV_DEBUG, LOCATION, NULL, @@ -3135,36 +3149,67 @@ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); - if (sa->sadb_sa_state != SADB_SASTATE_MATURE && + if (sa->sadb_sa_state != SADB_SASTATE_LARVAL && + sa->sadb_sa_state != SADB_SASTATE_MATURE && sa->sadb_sa_state != SADB_SASTATE_DYING) { msg = next; continue; } - /* delete in/outbound SAs */ + /* check in/outbound SAs */ if (CMPSADDR(iph1->remote, dst) && CMPSADDR(iph1->remote, src)) { msg = next; continue; } + iph2 = getph2byspid(sa->sadb_sa_spi); + + /* Check if there is another valid ISAKMP-SA */ + if (new_iph1 != NULL) { + + if (iph2 == NULL) { + /* No handler... still send a pfkey_delete message, but log this !*/ + plog(LLV_INFO, LOCATION, NULL, + "Unknown IPsec-SA spi=%u, hmmmm?\n", + ntohl(sa->sadb_sa_spi)); + }else{ + + /* + * If we have a new ph1, do not purge IPsec-SAs binded + * to a different ISAKMP-SA, or not binded anymore + */ + if (iph2->ph1 != iph1) + continue; + + /* If the ph2handle is established, do not purge IPsec-SA */ + if (iph2->status == PHASE2ST_ESTABLISHED || + iph2->status == PHASE2ST_EXPIRED) { + + plog(LLV_INFO, LOCATION, NULL, + "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n", + ntohl(sa->sadb_sa_spi), + isakmp_pindex(&(new_iph1->index), new_iph1->msgid)); + + continue; + } + } + } + + pfkey_send_delete(lcconf->sock_pfkey, msg->sadb_msg_satype, IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi); - /* - * delete a relative phase 2 handler. - * continue to process if no relative phase 2 handler - * exists. - */ - while ((iph2 = getph2bysaddr(src, dst)) != NULL) { + /* delete a relative phase 2 handle. */ + if (iph2 != NULL) { delete_spd(iph2); unbindph12(iph2); remph2(iph2); delph2(iph2); } - + plog(LLV_INFO, LOCATION, NULL, "purged IPsec-SA spi=%u.\n", ntohl(sa->sadb_sa_spi)); @@ -3183,7 +3228,6 @@ if (iph1->sce) SCHED_KILL(iph1->sce); - iph1->status = PHASE1ST_EXPIRED; iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); } |