Index: src/racoon/isakmp.c
===================================================================
RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/isakmp.c,v
retrieving revision 1.63
diff -u -r1.63 isakmp.c
--- a/src/racoon/isakmp.c	21 Oct 2010 06:15:28 -0000	1.63
+++ b/src/racoon/isakmp.c	29 Oct 2010 10:51:28 -0000
@@ -130,6 +130,10 @@
 #  define SOL_UDP IPPROTO_UDP
 # endif /* __NetBSD__ / __FreeBSD__ */
 
+vchar_t *postponed_buf;
+struct sockaddr_storage postponed_remote;
+struct sockaddr_storage postponed_local;
+
 static int nostate1 __P((struct ph1handle *, vchar_t *));
 static int nostate2 __P((struct ph2handle *, vchar_t *));
 
@@ -177,7 +181,7 @@
 
 static u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
 
-static int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *));
+/* static int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *)); */
 static int ph1_main __P((struct ph1handle *, vchar_t *));
 static int quick_main __P((struct ph2handle *, vchar_t *));
 static int isakmp_ph1begin_r __P((vchar_t *,
@@ -374,10 +378,17 @@
 	}
 
 	/* isakmp main routine */
-	if (isakmp_main(buf, (struct sockaddr *)&remote,
-			(struct sockaddr *)&local) != 0) goto end;
-
-	error = 0;
+	res = isakmp_main(buf, (struct sockaddr *)&remote,
+			  (struct sockaddr *)&local);
+	if (res == 0) {
+		error = 0;
+	} else if (res == -42424 && postponed_buf == NULL) {
+		postponed_buf    = buf;
+		postponed_remote = remote;
+		postponed_local  = local;
+		buf              = NULL;
+		error = 0;
+	}
 
 end:
 	if (tmpbuf != NULL)
@@ -390,7 +401,7 @@
 /*
  * main processing to handle isakmp payload
  */
-static int
+int
 isakmp_main(msg, remote, local)
 	vchar_t *msg;
 	struct sockaddr *remote, *local;
@@ -399,6 +410,7 @@
 	isakmp_index *index = (isakmp_index *)isakmp;
 	u_int32_t msgid = isakmp->msgid;
 	struct ph1handle *iph1;
+	int rc;
 
 #ifdef HAVE_PRINT_ISAKMP_C
 	isakmp_printpacket(msg, remote, local, 0);
@@ -604,12 +616,14 @@
 #endif
 
 		/* call main process of phase 1 */
-		if (ph1_main(iph1, msg) < 0) {
-			plog(LLV_ERROR, LOCATION, iph1->remote,
-				"phase1 negotiation failed.\n");
-			remph1(iph1);
-			delph1(iph1);
-			return -1;
+		if ((rc=ph1_main(iph1, msg)) < 0) {
+			if (rc != -42424) {
+				plog(LLV_ERROR, LOCATION, iph1->remote,
+					"phase1 negotiation failed.\n");
+				remph1(iph1);
+				delph1(iph1);
+			}
+			return rc;
 		}
 		break;
 
@@ -813,10 +827,11 @@
 				"failed to pre-process ph1 packet (side: %d, status %d).\n",
 				iph1->side, iph1->status);
 			return -1;
-		} else {
-			/* ignore the error and keep phase 1 handler */
-			return 0;
 		}
+		if (error == -42424)
+			return error;
+		/* ignore the error and keep phase 1 handler */
+		return 0;
 	}
 
 #ifndef ENABLE_FRAG
Index: src/racoon/isakmp_ident.c
===================================================================
RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/isakmp_ident.c,v
retrieving revision 1.13
diff -u -r1.13 isakmp_ident.c
--- a/src/racoon/isakmp_ident.c	18 Sep 2009 10:31:11 -0000	1.13
+++ b/src/racoon/isakmp_ident.c	29 Oct 2010 10:51:29 -0000
@@ -1128,6 +1128,11 @@
 		goto end;
 	}
 
+	if (postponed_buf != msg) {
+		error = -42424;
+		goto end;
+	}
+
 	/* validate the type of next payload */
 	pbuf = isakmp_parse(msg);
 	if (pbuf == NULL)
Index: src/racoon/isakmp_var.h
===================================================================
RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h,v
retrieving revision 1.16
diff -u -r1.16 isakmp_var.h
--- a/src/racoon/isakmp_var.h	3 Sep 2009 09:29:07 -0000	1.16
+++ b/src/racoon/isakmp_var.h	29 Oct 2010 10:51:29 -0000
@@ -141,4 +141,10 @@
 u_int32_t setscopeid __P((struct sockaddr *, struct sockaddr *));
 #endif
 
+int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *));
+
+extern vchar_t *postponed_buf;
+extern struct sockaddr_storage postponed_remote;
+extern struct sockaddr_storage postponed_local;
+
 #endif /* _ISAKMP_VAR_H */
Index: src/racoon/session.c
===================================================================
RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/session.c,v
retrieving revision 1.28
diff -u -r1.28 session.c
--- a/src/racoon/session.c	21 Oct 2010 06:15:28 -0000	1.28
+++ b/src/racoon/session.c	29 Oct 2010 10:51:29 -0000
@@ -172,7 +172,7 @@
 int
 session(void)
 {
-	struct timeval *timeout;
+	struct timeval *timeout, to_zero = { 0, 0 };
 	int error;
 	char pid_file[MAXPATHLEN];
 	FILE *fp;
@@ -295,6 +295,8 @@
 
 		/* scheduling */
 		timeout = schedular();
+		if (postponed_buf != NULL)
+			timeout = &to_zero;
 
 		/* schedular can change select() mask, so we reset
 		 * the working copy here */
@@ -332,6 +334,14 @@
 				break;
 		}
 
+		if (count == 0 && postponed_buf != NULL) {
+			(void) isakmp_main(
+				postponed_buf,
+				(struct sockaddr *) &postponed_remote,
+				(struct sockaddr *) &postponed_local);
+			vfree(postponed_buf);
+			postponed_buf = NULL;
+		}
 	}
 }