Change struct sched to be allocated be the caller to avoid some memory trunk
authortteras <tteras@NetBSD.org>
Fri, 19 Sep 2008 11:01:08 +0000
branchtrunk
changeset 173451 dbba31de1fd6
parent 173450 20b91edb9761
child 173452 898c2528507b
Change struct sched to be allocated be the caller to avoid some memory allocations. Optimize scheduling algorithm to not scan all entries in the main loop.
crypto/dist/ipsec-tools/ChangeLog
crypto/dist/ipsec-tools/src/racoon/handler.c
crypto/dist/ipsec-tools/src/racoon/handler.h
crypto/dist/ipsec-tools/src/racoon/isakmp.c
crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c
crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c
crypto/dist/ipsec-tools/src/racoon/isakmp_var.h
crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c
crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h
crypto/dist/ipsec-tools/src/racoon/nattraversal.c
crypto/dist/ipsec-tools/src/racoon/pfkey.c
crypto/dist/ipsec-tools/src/racoon/pfkey.h
crypto/dist/ipsec-tools/src/racoon/schedule.c
crypto/dist/ipsec-tools/src/racoon/schedule.h
crypto/dist/ipsec-tools/src/racoon/session.c
--- a/crypto/dist/ipsec-tools/ChangeLog	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/ChangeLog	Fri Sep 19 11:01:08 2008 +0000
@@ -1,3 +1,10 @@
+2008-09-19  Timo Teras  <timo.teras@iki.fi>
+	* src/racoon/{schedule.c|schedule.h|session.c|isakmp.c|
+	  isakmp_var.h|handler.c|handler.h|isakmp_quick.c|pfkey.c|pfkey.h|
+	  isakmp_inf.c|isakmp_xauth.c|isakmp_xauth.h|nattraversal.c}:
+	  Change struct sched to be allocated be the caller and optimize
+	  scheduler to be faster.
+
 2008-09-17  Yvan Vanhullebus  <vanhu@netasq.com>
 	* src/racoon/isakmp_inf.c: Fixed port match in purge_ipsec_spi()
 	  when NAT-T enabled and trying to purge non NAT-T SAs.
--- a/crypto/dist/ipsec-tools/src/racoon/handler.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/handler.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: handler.c,v 1.19 2008/03/06 00:34:11 mgrooms Exp $	*/
+/*	$NetBSD: handler.c,v 1.20 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
 
@@ -85,10 +85,10 @@
 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
+static struct sched sc_sweep = SCHED_INITIALIZER();
 
 static void del_recvdpkt __P((struct recvdpkt *));
 static void rem_recvdpkt __P((struct recvdpkt *));
-static void sweep_recvdpkt __P((void *));
 
 /*
  * functions about management of the isakmp status table
@@ -271,7 +271,6 @@
 	iph1->dpd_lastack = 0;
 	iph1->dpd_seq = 0;
 	iph1->dpd_fails = 0;
-	iph1->dpd_r_u = NULL;
 #endif
 	evt_list_init(&iph1->evt_listeners);
 
@@ -308,8 +307,10 @@
 #endif
 
 #ifdef ENABLE_DPD
-	SCHED_KILL(iph1->dpd_r_u);
+	sched_cancel(&iph1->dpd_r_u);
 #endif
+	sched_cancel(&iph1->sce);
+	sched_cancel(&iph1->scr);
 
 	if (iph1->remote) {
 		racoon_free(iph1->remote);
@@ -325,13 +326,7 @@
 	}
 
 	VPTRINIT(iph1->authstr);
-
-	sched_scrub_param(iph1);
-	iph1->sce = NULL;
-	iph1->scr = NULL;
-
 	VPTRINIT(iph1->sendbuf);
-
 	VPTRINIT(iph1->dhpriv);
 	VPTRINIT(iph1->dhpub);
 	VPTRINIT(iph1->dhpub_p);
@@ -504,7 +499,7 @@
 			 */
 			if(p->status < PHASE2ST_ESTABLISHED &&
 			   p->retry_counter == 0
-			   && p->sce == NULL && p->scr == NULL){
+			   && p->sce.func == NULL && p->scr.func == NULL) {
 				plog(LLV_DEBUG, LOCATION, NULL,
 					 "Zombie ph2 found, expiring it\n");
 				isakmp_ph2expire(p);
@@ -598,9 +593,8 @@
 {
 	evt_list_cleanup(&iph2->evt_listeners);
 
-	sched_scrub_param(iph2);
-	iph2->sce = NULL;
-	iph2->scr = NULL;
+	sched_cancel(&iph2->sce);
+	sched_cancel(&iph2->scr);
 
 	VPTRINIT(iph2->sendbuf);
 	VPTRINIT(iph2->msg1);
@@ -1020,9 +1014,9 @@
 	LIST_REMOVE(r, chain);
 }
 
-void
+static void
 sweep_recvdpkt(dummy)
-	void *dummy;
+	struct sched *dummy;
 {
 	struct recvdpkt *r, *next;
 	time_t t, lt;
@@ -1042,7 +1036,7 @@
 		}
 	}
 
-	sched_new(lt, sweep_recvdpkt, NULL);
+	sched_schedule(&sc_sweep, lt, sweep_recvdpkt);
 }
 
 void
@@ -1052,7 +1046,7 @@
 
 	LIST_INIT(&rcptree);
 
-	sched_new(lt, sweep_recvdpkt, NULL);
+	sched_schedule(&sc_sweep, lt, sweep_recvdpkt);
 }
 
 #ifdef ENABLE_HYBRID
@@ -1325,7 +1319,7 @@
 		isakmp_info_send_d1(iph1);
 	}
 	iph1->status = PHASE1ST_EXPIRED;
-	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+	sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub);
 }
 
 
--- a/crypto/dist/ipsec-tools/src/racoon/handler.h	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/handler.h	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: handler.h,v 1.14 2008/07/14 05:45:15 tteras Exp $	*/
+/*	$NetBSD: handler.h,v 1.15 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */
 
@@ -41,6 +41,7 @@
 
 #include "isakmp_var.h"
 #include "oakley.h"
+#include "schedule.h"
 #include "evt.h"
 
 /* Phase 1 handler */
@@ -141,9 +142,9 @@
 	struct isakmp_frag_item *frag_chain;	/* Received fragments */
 #endif
 
-	struct sched *sce;		/* schedule for expire */
+	struct sched sce;		/* schedule for expire */
 
-	struct sched *scr;		/* schedule for resend */
+	struct sched scr;		/* schedule for resend */
 	int retry_counter;		/* for resend. */
 	vchar_t *sendbuf;		/* buffer for re-sending */
 
@@ -202,7 +203,7 @@
 	time_t		dpd_lastack;	/* Last ack received */
 	u_int16_t	dpd_seq;		/* DPD seq number to receive */
 	u_int8_t	dpd_fails;		/* number of failures */
-	struct sched	*dpd_r_u;
+	struct sched	dpd_r_u;
 #endif
 
 	u_int32_t msgid2;		/* msgid counter for Phase 2 */
@@ -265,8 +266,8 @@
 	int status;			/* ipsec sa status */
 	u_int8_t side;			/* INITIATOR or RESPONDER */
 
-	struct sched *sce;		/* schedule for expire */
-	struct sched *scr;		/* schedule for resend */
+	struct sched sce;		/* schedule for expire */
+	struct sched scr;		/* schedule for resend */
 	int retry_counter;		/* for resend. */
 	vchar_t *sendbuf;		/* buffer for re-sending */
 	vchar_t *msg1;			/* buffer for re-sending */
@@ -351,8 +352,6 @@
 	time_t time_send;		/* timestamp to send a packet */
 	time_t created;			/* timestamp to create a queue */
 
-	struct sched *scr;		/* schedule for resend, may not used */
-
 	LIST_ENTRY(recvdpkt) chain;
 };
 
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp.c,v 1.39 2008/08/29 00:31:37 gmcgarry Exp $	*/
+/*	$NetBSD: isakmp.c,v 1.40 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
 
@@ -833,7 +833,7 @@
 	VPTRINIT(iph1->sendbuf);
 
 	/* turn off schedule */
-	SCHED_KILL(iph1->scr);
+	sched_cancel(&iph1->scr);
 
 	/* send */
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
@@ -864,8 +864,8 @@
 		(void)time(&iph1->created);
 
 		/* add to the schedule to expire, and seve back pointer. */
-		iph1->sce = sched_new(iph1->approval->lifetime,
-		    isakmp_ph1expire_stub, iph1);
+		sched_schedule(&iph1->sce, iph1->approval->lifetime,
+			       isakmp_ph1expire_stub);
 #ifdef ENABLE_HYBRID
 		if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
 			switch(AUTHMETHOD(iph1)) {
@@ -996,7 +996,7 @@
 	VPTRINIT(iph2->sendbuf);
 
 	/* turn off schedule */
-	SCHED_KILL(iph2->scr);
+	sched_cancel(&iph2->scr);
 
 	/* send */
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
@@ -1877,19 +1877,11 @@
 /* called from scheduler */
 void
 isakmp_ph1resend_stub(p)
-	void *p;
+	struct sched *p;
 {
-	struct ph1handle *iph1;
-
-	iph1=(struct ph1handle *)p;
-	if(isakmp_ph1resend(iph1) < 0){
-		if(iph1->scr != NULL){
-			/* Should not happen...
-			 */
-			sched_kill(iph1->scr);
-			iph1->scr=NULL;
-		}
-
+	struct ph1handle *iph1 = container_of(p, struct ph1handle, scr);
+
+	if (isakmp_ph1resend(iph1) < 0) {
 		remph1(iph1);
 		delph1(iph1);
 	}
@@ -1924,8 +1916,8 @@
 
 	iph1->retry_counter--;
 
-	iph1->scr = sched_new(iph1->rmconf->retry_interval,
-		isakmp_ph1resend_stub, iph1);
+	sched_schedule(&iph1->scr, iph1->rmconf->retry_interval,
+		       isakmp_ph1resend_stub);
 
 	return 0;
 }
@@ -1933,13 +1925,11 @@
 /* called from scheduler */
 void
 isakmp_ph2resend_stub(p)
-	void *p;
+	struct sched *p;
 {
-	struct ph2handle *iph2;
-
-	iph2=(struct ph2handle *)p;
-
-	if(isakmp_ph2resend(iph2) < 0){
+	struct ph2handle *iph2 = container_of(p, struct ph2handle, scr);
+
+	if (isakmp_ph2resend(iph2) < 0) {
 		unbindph12(iph2);
 		remph2(iph2);
 		delph2(iph2);
@@ -1982,8 +1972,8 @@
 
 	iph2->retry_counter--;
 
-	iph2->scr = sched_new(iph2->ph1->rmconf->retry_interval,
-		isakmp_ph2resend_stub, iph2);
+	sched_schedule(&iph2->scr, iph2->ph1->rmconf->retry_interval,
+		       isakmp_ph2resend_stub);
 
 	return 0;
 }
@@ -1991,10 +1981,9 @@
 /* called from scheduler */
 void
 isakmp_ph1expire_stub(p)
-	void *p;
+	struct sched *p;
 {
-
-	isakmp_ph1expire((struct ph1handle *)p);
+	isakmp_ph1expire(container_of(p, struct ph1handle, sce));
 }
 
 void
@@ -2003,9 +1992,7 @@
 {
 	char *src, *dst;
 
-	SCHED_KILL(iph1->sce);
-
-	if(iph1->status != PHASE1ST_EXPIRED){
+	if (iph1->status != PHASE1ST_EXPIRED) {
 		src = racoon_strdup(saddr2str(iph1->local));
 		dst = racoon_strdup(saddr2str(iph1->remote));
 		STRDUP_FATAL(src);
@@ -2024,20 +2011,20 @@
 	 * the phase1 deletion is postponed until there is no phase2.
 	 */
 	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
-		iph1->sce = sched_new(1, isakmp_ph1expire_stub, iph1);
+		sched_schedule(&iph1->sce, 1, isakmp_ph1expire_stub);
 		return;
 	}
 
-	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+	sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub);
 }
 
 /* called from scheduler */
 void
 isakmp_ph1delete_stub(p)
-	void *p;
+	struct sched *p;
 {
 
-	isakmp_ph1delete((struct ph1handle *)p);
+	isakmp_ph1delete(container_of(p, struct ph1handle, sce));
 }
 
 void
@@ -2046,10 +2033,8 @@
 {
 	char *src, *dst;
 
-	SCHED_KILL(iph1->sce);
-
 	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
-		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+		sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub);
 		return;
 	}
 
@@ -2081,10 +2066,10 @@
  */
 void
 isakmp_ph2expire_stub(p)
-	void *p;
+	struct sched *p;
 {
 
-	isakmp_ph2expire((struct ph2handle *)p);
+	isakmp_ph2expire(container_of(p, struct ph2handle, sce));
 }
 
 void
@@ -2093,8 +2078,6 @@
 {
 	char *src, *dst;
 
-	SCHED_KILL(iph2->sce);
-
 	src = racoon_strdup(saddrwop2str(iph2->src));
 	dst = racoon_strdup(saddrwop2str(iph2->dst));
 	STRDUP_FATAL(src);
@@ -2106,19 +2089,16 @@
 	racoon_free(dst);
 
 	iph2->status = PHASE2ST_EXPIRED;
-
-	iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
-
-	return;
+	sched_schedule(&iph2->sce, 1, isakmp_ph2delete_stub);
 }
 
 /* called from scheduler */
 void
 isakmp_ph2delete_stub(p)
-	void *p;
+	struct sched *p;
 {
 
-	isakmp_ph2delete((struct ph2handle *)p);
+	isakmp_ph2delete(container_of(p, struct ph2handle, sce));
 }
 
 void
@@ -2127,8 +2107,6 @@
 {
 	char *src, *dst;
 
-	SCHED_KILL(iph2->sce);
-
 	src = racoon_strdup(saddrwop2str(iph2->src));
 	dst = racoon_strdup(saddrwop2str(iph2->dst));
 	STRDUP_FATAL(src);
@@ -2200,10 +2178,8 @@
 
 	/* no ISAKMP-SA found. */
 	if (iph1 == NULL) {
-		struct sched *sc;
-
 		iph2->retry_checkph1 = lcconf->retry_checkph1;
-		sc = sched_new(1, isakmp_chkph1there_stub, iph2);
+		sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
 		plog(LLV_INFO, LOCATION, NULL,
 			"IPsec-SA request for %s queued "
 			"due to no phase1 found.\n",
@@ -2211,7 +2187,7 @@
 
 		/* start phase 1 negotiation as a initiator. */
 		if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) == NULL) {
-			SCHED_KILL(sc);
+			sched_cancel(&iph2->sce);
 			return -1;
 		}
 
@@ -2222,7 +2198,7 @@
 	/* found ISAKMP-SA, but on negotiation. */
 	if (iph1->status != PHASE1ST_ESTABLISHED) {
 		iph2->retry_checkph1 = lcconf->retry_checkph1;
-		sched_new(1, isakmp_chkph1there_stub, iph2);
+		sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
 		plog(LLV_INFO, LOCATION, iph2->dst,
 			"request for establishing IPsec-SA was queued "
 			"due to no phase1 found.\n");
@@ -2348,9 +2324,9 @@
 /* called by scheduler */
 void
 isakmp_chkph1there_stub(p)
-	void *p;
+	struct sched *p;
 {
-	isakmp_chkph1there((struct ph2handle *)p);
+	isakmp_chkph1there(container_of(p, struct ph2handle, sce));
 }
 
 void
@@ -2426,7 +2402,7 @@
 	plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
 
 	/* no isakmp-sa found */
-	sched_new(1, isakmp_chkph1there_stub, iph2);
+	sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
 
 	return;
 }
@@ -3401,9 +3377,7 @@
 		 "purged ISAKMP-SA spi=%s.\n",
 		 isakmp_pindex(&(iph1->index), iph1->msgid));
 
-	SCHED_KILL(iph1->sce);
-
-	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+	sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub);
 }
 
 void 
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_inf.c,v 1.32 2008/09/17 12:39:07 vanhu Exp $	*/
+/*	$NetBSD: isakmp_inf.c,v 1.33 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
 
@@ -107,7 +107,7 @@
 	struct isakmp_pl_ru *, u_int32_t));
 static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
 	struct isakmp_pl_ru *, u_int32_t));
-static void isakmp_info_send_r_u __P((void *));
+static void isakmp_info_send_r_u __P((struct sched *));
 #endif
 
 static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
@@ -518,7 +518,7 @@
 		if(del_ph1 != NULL){
 
 			evt_phase1(iph1, EVT_PHASE1_PEER_DELETED, NULL);
-			SCHED_KILL(del_ph1->scr);
+			sched_cancel(&del_ph1->scr);
 
 			/*
 			 * Do not delete IPsec SAs when receiving an IKE delete notification.
@@ -1117,9 +1117,8 @@
 			s_ipsecdoi_proto(proto),
 			isakmp_pindex(&spi[i], 0));
 
-		SCHED_KILL(iph1->sce);
 		iph1->status = PHASE1ST_EXPIRED;
-		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+		sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub);
 	}
 }
 
@@ -1564,8 +1563,7 @@
 	/* Useless ??? */
 	iph1->dpd_lastack = time(NULL);
 
-	SCHED_KILL(iph1->dpd_r_u);
-
+	sched_cancel(&iph1->dpd_r_u);
 	isakmp_sched_r_u(iph1, 0);
 
 	plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
@@ -1580,10 +1578,10 @@
  * send DPD R-U-THERE payload in Informational exchange.
  */
 static void
-isakmp_info_send_r_u(arg)
-	void *arg;
+isakmp_info_send_r_u(sc)
+	struct sched *sc;
 {
-	struct ph1handle *iph1 = arg;
+	struct ph1handle *iph1 = container_of(sc, struct ph1handle, dpd_r_u);
 
 	/* create R-U-THERE payload */
 	struct isakmp_pl_ru *ru;
@@ -1593,8 +1591,6 @@
 
 	plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
 
-	iph1->dpd_r_u=NULL;
-
 	if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
 
 		plog(LLV_INFO, LOCATION, iph1->remote,
@@ -1674,11 +1670,11 @@
 		return 0;
 
 	if(retry)
-		iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
-								  isakmp_info_send_r_u, iph1);
+		sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_retry,
+			       isakmp_info_send_r_u);
 	else
-		iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
-								  isakmp_info_send_r_u, iph1);
+		sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_interval,
+			       isakmp_info_send_r_u);
 
 	return 0;
 }
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_quick.c,v 1.19 2008/07/14 05:45:15 tteras Exp $	*/
+/*	$NetBSD: isakmp_quick.c,v 1.20 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */
 
@@ -99,6 +99,33 @@
 static int get_sainfo_r __P((struct ph2handle *));
 static int get_proposal_r __P((struct ph2handle *));
 static int ph2_recv_n __P((struct ph2handle *, struct isakmp_gen *));
+static void quick_timeover_stub __P((struct sched *));
+static void quick_timeover __P((struct ph2handle *));
+
+/* called from scheduler */
+static void
+quick_timeover_stub(p)
+	struct sched *p;
+{
+	quick_timeover(container_of(p, struct ph2handle, sce));
+}
+
+static void
+quick_timeover(iph2)
+	struct ph2handle *iph2;
+{
+	plog(LLV_ERROR, LOCATION, NULL,
+		"%s give up to get IPsec-SA due to time up to wait.\n",
+		saddrwop2str(iph2->dst));
+
+	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
+	if (iph2->side == INITIATOR)
+		pk_sendeacquire(iph2);
+
+	unbindph12(iph2);
+	remph2(iph2);
+	delph2(iph2);
+}
 
 /* %%%
  * Quick Mode
@@ -139,8 +166,8 @@
 
 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
 
-	iph2->sce = sched_new(lcconf->wait_ph2complete,
-		pfkey_timeover_stub, iph2);
+	sched_schedule(&iph2->sce, lcconf->wait_ph2complete,
+		       quick_timeover_stub);
 
 	error = 0;
 
@@ -1390,8 +1417,8 @@
 
 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
 
-	iph2->sce = sched_new(lcconf->wait_ph2complete,
-		pfkey_timeover_stub, iph2);
+	sched_schedule(&iph2->sce, lcconf->wait_ph2complete,
+		       quick_timeover_stub);
 
 	error = 0;
 
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_var.h,v 1.9 2008/03/06 00:46:04 mgrooms Exp $	*/
+/*	$NetBSD: isakmp_var.h,v 1.10 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: isakmp_var.h,v 1.12 2005/05/07 14:45:31 manubsd Exp */
 
@@ -75,23 +75,23 @@
 extern void isakmp_close __P((void));
 extern int isakmp_send __P((struct ph1handle *, vchar_t *));
 
-extern void isakmp_ph1resend_stub __P((void *));
+extern void isakmp_ph1resend_stub __P((struct sched *));
 extern int isakmp_ph1resend __P((struct ph1handle *));
-extern void isakmp_ph2resend_stub __P((void *));
+extern void isakmp_ph2resend_stub __P((struct sched *));
 extern int isakmp_ph2resend __P((struct ph2handle *));
-extern void isakmp_ph1expire_stub __P((void *));
+extern void isakmp_ph1expire_stub __P((struct sched *));
 extern void isakmp_ph1expire __P((struct ph1handle *));
-extern void isakmp_ph1delete_stub __P((void *));
+extern void isakmp_ph1delete_stub __P((struct sched *));
 extern void isakmp_ph1delete __P((struct ph1handle *));
-extern void isakmp_ph2expire_stub __P((void *));
+extern void isakmp_ph2expire_stub __P((struct sched *));
 extern void isakmp_ph2expire __P((struct ph2handle *));
-extern void isakmp_ph2delete_stub __P((void *));
+extern void isakmp_ph2delete_stub __P((struct sched *));
 extern void isakmp_ph2delete __P((struct ph2handle *));
 
 extern int isakmp_get_sainfo __P((struct ph2handle *, struct secpolicy *, struct secpolicy *));
 extern int isakmp_post_acquire __P((struct ph2handle *));
 extern int isakmp_post_getspi __P((struct ph2handle *));
-extern void isakmp_chkph1there_stub __P((void *));
+extern void isakmp_chkph1there_stub __P((struct sched *));
 extern void isakmp_chkph1there __P((struct ph2handle *));
 
 extern caddr_t isakmp_set_attr_v __P((caddr_t, int, caddr_t, int));
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_xauth.c,v 1.15 2008/07/22 01:30:02 mgrooms Exp $	*/
+/*	$NetBSD: isakmp_xauth.c,v 1.16 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
 
@@ -330,7 +330,7 @@
 		if (throttle_delay != 0) {
 			struct xauth_reply_arg *xra;
 
-			if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
+			if ((xra = racoon_calloc(1, sizeof(*xra))) == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL, 
 				    "malloc failed, bypass throttling\n");
 				return xauth_reply(iph1, port, id, res);
@@ -345,7 +345,8 @@
 			xra->port = port;
 			xra->id = id;
 			xra->res = res;
-			sched_new(throttle_delay, xauth_reply_stub, xra);
+			sched_schedule(&xra->sc, throttle_delay,
+				       xauth_reply_stub);
 		} else {
 			return xauth_reply(iph1, port, id, res);
 		}
@@ -355,10 +356,10 @@
 }
 
 void 
-xauth_reply_stub(args)
-	void *args;
+xauth_reply_stub(sc)
+	struct sched *sc;
 {
-	struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
+	struct xauth_reply_arg *xra = container_of(sc, struct xauth_reply_arg, sc);
 	struct ph1handle *iph1;
 
 	if ((iph1 = getph1byindex(&xra->index)) != NULL)
@@ -368,7 +369,6 @@
 		    "Delayed Xauth reply: phase 1 no longer exists.\n"); 
 
 	racoon_free(xra);
-	return;
 }
 
 int
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_xauth.h,v 1.5 2008/07/22 01:30:02 mgrooms Exp $	*/
+/*	$NetBSD: isakmp_xauth.h,v 1.6 2008/09/19 11:01:08 tteras Exp $	*/
 
 /*	$KAME$ */
 
@@ -34,6 +34,8 @@
 #ifndef _ISAKMP_XAUTH_H
 #define _ISAKMP_XAUTH_H
 
+#include "schedule.h"
+
 /* ISAKMP mode config attribute types specific to the Xauth vendor ID */
 #define	XAUTH_TYPE                16520
 #define	XAUTH_USER_NAME           16521
@@ -90,6 +92,7 @@
 #define XAUTHST_OK	2
 
 struct xauth_reply_arg {
+	struct sched sc;
 	isakmp_index index;
 	int port;
 	int id;
@@ -107,7 +110,7 @@
 vchar_t *isakmp_xauth_req(struct ph1handle *, struct isakmp_data *);
 vchar_t *isakmp_xauth_set(struct ph1handle *, struct isakmp_data *);
 void xauth_rmstate(struct xauth_state *);
-void xauth_reply_stub(void *);
+void xauth_reply_stub(struct sched *);
 int xauth_reply(struct ph1handle *, int, int, int);
 int xauth_rmconf_used(struct xauth_rmconf **);
 void xauth_rmconf_delete(struct xauth_rmconf **);
--- a/crypto/dist/ipsec-tools/src/racoon/nattraversal.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/nattraversal.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nattraversal.c,v 1.6 2006/09/09 16:22:09 manu Exp $	*/
+/*	$NetBSD: nattraversal.c,v 1.7 2008/09/19 11:01:08 tteras Exp $	*/
 
 /*
  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
@@ -77,6 +77,7 @@
 };
 
 static TAILQ_HEAD(_natt_ka_addrs, natt_ka_addrs) ka_tree;
+static struct sched sc_natt = SCHED_INITIALIZER();
 
 /*
  * check if the given vid is NAT-T.
@@ -321,7 +322,7 @@
 
 /* NAT keepalive functions */
 static void
-natt_keepalive_send (void *param)
+natt_keepalive_send (struct sched *param)
 {
   struct natt_ka_addrs	*ka, *next = NULL;
   char keepalive_packet[] = { 0xff };
@@ -346,7 +347,7 @@
 	   strerror (errno));
   }
   
-  sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL);
+  sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send);
 }
 
 void
@@ -356,7 +357,7 @@
 
   /* To disable sending KAs set natt_ka_interval=0 */
   if (lcconf->natt_ka_interval > 0)
-    sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL);
+    sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send);
 }
 
 int
--- a/crypto/dist/ipsec-tools/src/racoon/pfkey.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/pfkey.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,6 +1,6 @@
-/*	$NetBSD: pfkey.c,v 1.32 2008/09/09 11:50:42 vanhu Exp $	*/
-
-/* $Id: pfkey.c,v 1.32 2008/09/09 11:50:42 vanhu Exp $ */
+/*	$NetBSD: pfkey.c,v 1.33 2008/09/19 11:01:08 tteras Exp $	*/
+
+/* $Id: pfkey.c,v 1.33 2008/09/19 11:01:08 tteras Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -815,35 +815,6 @@
 	return -1;
 }
 
-/* called from scheduler */
-void
-pfkey_timeover_stub(p)
-	void *p;
-{
-
-	pfkey_timeover((struct ph2handle *)p);
-}
-
-void
-pfkey_timeover(iph2)
-	struct ph2handle *iph2;
-{
-	plog(LLV_ERROR, LOCATION, NULL,
-		"%s give up to get IPsec-SA due to time up to wait.\n",
-		saddrwop2str(iph2->dst));
-	SCHED_KILL(iph2->sce);
-
-	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
-	if (iph2->side == INITIATOR)
-		pk_sendeacquire(iph2);
-
-	unbindph12(iph2);
-	remph2(iph2);
-	delph2(iph2);
-
-	return;
-}
-
 /*%%%*/
 /* send getspi message per ipsec protocol per remote address */
 /*
@@ -1313,7 +1284,7 @@
 		return 0;
 
 	/* turn off the timer for calling pfkey_timeover() */
-	SCHED_KILL(iph2->sce);
+	sched_cancel(&iph2->sce);
 
 	/* update status */
 	iph2->status = PHASE2ST_ESTABLISHED;
@@ -1329,7 +1300,7 @@
 	iph2->ph1->ph2cnt++;
 
 	/* turn off schedule */
-	SCHED_KILL(iph2->scr);
+	sched_cancel(&iph2->scr);
 
 	/* Force the update of ph2's ports, as there is at least one
 	 * situation where they'll mismatch with ph1's values
@@ -1346,8 +1317,8 @@
 	 */
 	unbindph12(iph2);
 
-	iph2->sce = sched_new(iph2->approval->lifetime,
-	    isakmp_ph2expire_stub, iph2);
+	sched_schedule(&iph2->sce, iph2->approval->lifetime,
+		       isakmp_ph2expire_stub);
 
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
 	return 0;
@@ -1659,7 +1630,7 @@
 	}
 
 	/* turn off the timer for calling isakmp_ph2expire() */ 
-	SCHED_KILL(iph2->sce);
+	sched_cancel(&iph2->sce);
 
 	iph2->status = PHASE2ST_EXPIRED;
 
--- a/crypto/dist/ipsec-tools/src/racoon/pfkey.h	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/pfkey.h	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey.h,v 1.5 2008/03/05 22:09:44 mgrooms Exp $	*/
+/*	$NetBSD: pfkey.h,v 1.6 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: pfkey.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */
 
@@ -61,9 +61,6 @@
 extern int pk_sendspdadd2 __P((struct ph2handle *));
 extern int pk_sendspddelete __P((struct ph2handle *));
 
-extern void pfkey_timeover_stub __P((void *));
-extern void pfkey_timeover __P((struct ph2handle *));
-
 extern u_int pfkey2ipsecdoi_proto __P((u_int));
 extern u_int ipsecdoi2pfkey_proto __P((u_int));
 extern u_int pfkey2ipsecdoi_mode __P((u_int));
--- a/crypto/dist/ipsec-tools/src/racoon/schedule.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/schedule.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,9 +1,10 @@
-/*	$NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
+/*	$NetBSD: schedule.c,v 1.5 2008/09/19 11:01:08 tteras Exp $	*/
 
 /*	$KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * Copyright (C) 2008 Timo Teras.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -68,7 +69,6 @@
 
 static TAILQ_HEAD(_schedtree, sched) sctree;
 
-static void sched_add __P((struct sched *));
 static time_t current_time __P((void));
 
 /*
@@ -81,30 +81,16 @@
 schedular()
 {
 	time_t now, delta;
-	struct sched *p, *next = NULL;
+	struct sched *p;
 
 	now = current_time();
-
-        for (p = TAILQ_FIRST(&sctree); p; p = next) {
-		/* if the entry has been daed, remove it */
-		if (p->dead)
-			goto next_schedule;
+	while (!TAILQ_EMPTY(&sctree) && TAILQ_FIRST(&sctree)->xtime <= now) {
+		void (*func)(struct sched *);
 
-		/* if the time hasn't come, proceed to the next entry */
-		if (now < p->xtime) {
-			next = TAILQ_NEXT(p, chain);
-			continue;
-		}
-
-		/* mark it with dead. and call the function. */
-		p->dead = 1;
-		if (p->func != NULL)
-			(p->func)(p->param);
-
-	   next_schedule:
-		next = TAILQ_NEXT(p, chain);
-		TAILQ_REMOVE(&sctree, p, chain);
-		racoon_free(p);
+		p = TAILQ_FIRST(&sctree);
+		func = p->func;
+		sched_cancel(p);
+		func(p);
 	}
 
 	p = TAILQ_FIRST(&sctree);
@@ -112,7 +98,6 @@
 		return NULL;
 
 	now = current_time();
-
 	delta = p->xtime - now;
 	timeout.tv_sec = delta < 0 ? 0 : delta;
 	timeout.tv_usec = 0;
@@ -123,55 +108,47 @@
 /*
  * add new schedule to schedule table.
  */
-struct sched *
-sched_new(tick, func, param)
+void
+sched_schedule(sc, tick, func)
+	struct sched *sc;
 	time_t tick;
-	void (*func) __P((void *));
-	void *param;
+	void (*func) __P((struct sched *));
 {
 	static long id = 1;
-	struct sched *new;
-
-	new = (struct sched *)racoon_malloc(sizeof(*new));
-	if (new == NULL)
-		return NULL;
+	struct sched *p;
 
-	memset(new, 0, sizeof(*new));
-	new->func = func;
-	new->param = param;
-
-	new->id = id++;
-	time(&new->created);
-	new->tick = tick;
-
-	new->xtime = current_time() + tick;
-	new->dead = 0;
+	sched_cancel(sc);
+	sc->func = func;
+	sc->id = id++;
+	time(&sc->created);
+	sc->tick = tick;
+	sc->xtime = current_time() + tick;
 
 	/* add to schedule table */
-	sched_add(new);
-
-	return(new);
-}
-
-/* add new schedule to schedule table */
-static void
-sched_add(sc)
-	struct sched *sc;
-{
-	struct sched *p;
-
 	TAILQ_FOREACH(p, &sctree, chain) {
-		if (sc->xtime < p->xtime) {
-			TAILQ_INSERT_BEFORE(p, sc, chain);
-			return;
-		}
+		if (sc->xtime < p->xtime)
+			break;
 	}
 	if (p == NULL)
 		TAILQ_INSERT_TAIL(&sctree, sc, chain);
+	else
+		TAILQ_INSERT_BEFORE(p, sc, chain);
+}
 
-	return;
+/*
+ * cancel scheduled callback
+ */
+void
+sched_cancel(sc)
+	struct sched *sc;
+{
+	if (sc->func != NULL) {
+		TAILQ_REMOVE(&sctree, sc, chain);
+		sc->func = NULL;
+	}
 }
 
+
 /* get current time.
  * if defined FIXY2038PROBLEM, base time is the time when called sched_init().
  * Otherwise, conform to time(3).
@@ -194,33 +171,6 @@
 #endif
 }
 
-void
-sched_kill(sc)
-	struct sched *sc;
-{
-	sc->dead = 1;
-
-	return;
-}
-
-/* XXX this function is probably unnecessary. */
-void
-sched_scrub_param(param)
-	void *param;
-{
-	struct sched *sc;
-
-	TAILQ_FOREACH(sc, &sctree, chain) {
-		if (sc->param == param) {
-			if (!sc->dead) {
-				plog(LLV_DEBUG, LOCATION, NULL,
-				    "an undead schedule has been deleted.\n");
-			}
-			sched_kill(sc);
-		}
-	}
-}
-
 /*
  * for debug
  */
@@ -281,8 +231,6 @@
 #endif
 
 	TAILQ_INIT(&sctree);
-
-	return;
 }
 
 #ifdef STEST
--- a/crypto/dist/ipsec-tools/src/racoon/schedule.h	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/schedule.h	Fri Sep 19 11:01:08 2008 +0000
@@ -1,9 +1,10 @@
-/*	$NetBSD: schedule.h,v 1.5 2007/03/21 14:28:59 vanhu Exp $	*/
+/*	$NetBSD: schedule.h,v 1.6 2008/09/19 11:01:08 tteras Exp $	*/
 
 /* Id: schedule.h,v 1.5 2006/05/03 21:53:42 vanhu Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * Copyright (C) 2008 Timo Teras.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -37,6 +38,21 @@
 #include <sys/queue.h>
 #include "gnuc.h"
 
+#ifndef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+
 /* scheduling table */
 /* the head is the nearest event. */
 struct sched {
@@ -45,10 +61,8 @@
 				 * if defined FIXY2038PROBLEM, this time
 				 * is from the time when called sched_init().
 				 */
-	void (*func) __P((void *)); /* call this function when timeout. */
-	void *param;		/* pointer to parameter */
+	void (*func) __P((struct sched *)); /* call this function when timeout. */
 
-	int dead;		/* dead or alive */
 	long id;		/* for debug */
 	time_t created;		/* for debug */
 	time_t tick;		/* for debug */
@@ -56,17 +70,7 @@
 	TAILQ_ENTRY(sched) chain;
 };
 
-/* cancel schedule */
-#define SCHED_KILL(s)                                                          \
-do {                                                                           \
-	if(s != NULL){	   														\
-		sched_kill(s);                                                         \
-		s = NULL;                                                              \
-	}\
-} while(0)
-
-/* must be called after it's called from scheduler. */
-#define SCHED_INIT(s)	(s) = NULL
+#define SCHED_INITIALIZER() { 0, NULL, }
 
 struct scheddump {
 	time_t xtime;
@@ -76,10 +80,11 @@
 };
 
 struct timeval *schedular __P((void));
-struct sched *sched_new __P((time_t, void (*func) __P((void *)), void *));
-void sched_kill __P((struct sched *));
+void sched_schedule __P((struct sched *, time_t,
+			 void (*func) __P((struct sched *))));
+void sched_cancel __P((struct sched *));
+
 int sched_dump __P((caddr_t *, int *));
 void sched_init __P((void));
-void sched_scrub_param __P((void *));
 
 #endif /* _SCHEDULE_H */
--- a/crypto/dist/ipsec-tools/src/racoon/session.c	Fri Sep 19 08:30:35 2008 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/session.c	Fri Sep 19 11:01:08 2008 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: session.c,v 1.15 2008/08/06 19:14:28 tteras Exp $	*/
+/*	$NetBSD: session.c,v 1.16 2008/09/19 11:01:08 tteras Exp $	*/
 
 /*	$KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $	*/
 
@@ -104,7 +104,7 @@
 static void init_signal __P((void));
 static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int))));
 static void check_sigreq __P((void));
-static void check_flushsa_stub __P((void *));
+static void check_flushsa_stub __P((struct sched *));
 static void check_flushsa __P((void));
 static int close_sockets __P((void));
 
@@ -113,6 +113,7 @@
 static int nfds = 0;
 static volatile sig_atomic_t sigreq[NSIG + 1];
 static int dying = 0;
+static struct sched scflushsa = SCHED_INITIALIZER();
 
 int
 session(void)
@@ -482,7 +483,7 @@
 #ifdef ENABLE_FASTQUIT
 			close_session();
 #else
-			sched_new(1, check_flushsa_stub, NULL);
+			sched_schedule(&scflushsa, 1, check_flushsa_stub);
 #endif
 			dying = 1;
 			break;
@@ -501,7 +502,7 @@
  */
 static void
 check_flushsa_stub(p)
-	void *p;
+	struct sched *p;
 {
 
 	check_flushsa();
@@ -563,7 +564,7 @@
 		vfree(buf);
 
 	if (n) {
-		sched_new(1, check_flushsa_stub, NULL);
+		sched_schedule(&scflushsa, 1, check_flushsa_stub);
 		return;
 	}