1/*	$NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu Exp $	*/
2
3/* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39
40#include <stdlib.h>
41#include <stdio.h>
42#include <string.h>
43#include <time.h>
44#include <errno.h>
45
46#include "var.h"
47#include "misc.h"
48#include "vmbuf.h"
49#include "plog.h"
50#include "sockmisc.h"
51#include "debug.h"
52#include "fsm.h"
53
54#ifdef ENABLE_HYBRID
55#include <resolv.h>
56#endif
57
58#include "schedule.h"
59#include "grabmyaddr.h"
60#include "algorithm.h"
61#include "crypto_openssl.h"
62#include "policy.h"
63#include "proposal.h"
64#include "isakmp_var.h"
65#include "isakmp.h"
66#ifdef ENABLE_HYBRID
67#include "isakmp_xauth.h"
68#include "isakmp_cfg.h"
69#endif
70#include "isakmp_inf.h"
71#include "oakley.h"
72#include "remoteconf.h"
73#include "localconf.h"
74#include "handler.h"
75#include "gcmalloc.h"
76#include "nattraversal.h"
77#include "ike_session.h"
78#include "isakmp_frag.h"
79
80#include "sainfo.h"
81
82#include "power_mgmt.h"
83
84extern LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree;
85static LIST_HEAD(_ctdtree_, contacted) ctdtree;
86static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
87
88static void ike_session_del_recvdpkt (struct recvdpkt *);
89static void ike_session_rem_recvdpkt (struct recvdpkt *);
90static void sweep_recvdpkt (void *);
91
92/*
93 * functions about management of the isakmp status table
94 */
95/* %%% management phase 1 handler */
96/*
97 * search for isakmpsa handler with isakmp index.
98 */
99
100extern caddr_t val2str (const char *, size_t);
101
102static phase1_handle_t *
103getph1byindex(ike_session_t *session, isakmp_index *index)
104{
105	phase1_handle_t *p = NULL;
106
107	LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
108		if (FSM_STATE_IS_EXPIRED(p->status))
109			continue;
110		if (memcmp(&p->index, index, sizeof(*index)) == 0)
111			return p;
112	}
113
114	return NULL;
115}
116
117phase1_handle_t *
118ike_session_getph1byindex(ike_session_t *session, isakmp_index *index)
119{
120    phase1_handle_t *p;
121    ike_session_t   *cur_session = NULL;
122
123    if (session)
124        return getph1byindex(session, index);
125
126    LIST_FOREACH(cur_session, &ike_session_tree, chain) {
127        if ((p = getph1byindex(cur_session, index)) != NULL)
128            return p;
129    }
130    return NULL;
131}
132
133
134/*
135 * search for isakmp handler by i_ck in index.
136 */
137
138static phase1_handle_t *
139getph1byindex0 (ike_session_t *session, isakmp_index *index)
140{
141    phase1_handle_t *p = NULL;
142
143    LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
144        if (FSM_STATE_IS_EXPIRED(p->status))
145            continue;
146        if (memcmp(&p->index.i_ck, &index->i_ck, sizeof(cookie_t)) == 0)
147            return p;
148    }
149    return NULL;
150}
151
152phase1_handle_t *
153ike_session_getph1byindex0(ike_session_t *session, isakmp_index *index)
154{
155    phase1_handle_t *p = NULL;
156    ike_session_t   *cur_session = NULL;
157
158    if (session)
159        return getph1byindex0(session, index);
160
161    LIST_FOREACH(cur_session, &ike_session_tree, chain) {
162        if ((p = getph1byindex0(cur_session, index)) != NULL)
163            return p;
164	}
165
166	return NULL;
167}
168
169/*
170 * search for isakmpsa handler by source and remote address.
171 * don't use port number to search because this function search
172 * with phase 2's destinaion.
173 */
174phase1_handle_t *
175ike_session_getph1byaddr(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
176{
177    phase1_handle_t *p = NULL;
178
179	plog(ASL_LEVEL_DEBUG, "getph1byaddr: start\n");
180	plog(ASL_LEVEL_DEBUG, "local: %s\n", saddr2str((struct sockaddr *)local));
181	plog(ASL_LEVEL_DEBUG, "remote: %s\n", saddr2str((struct sockaddr *)remote));
182
183	LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
184		if (FSM_STATE_IS_EXPIRED(p->status))
185			continue;
186		plog(ASL_LEVEL_DEBUG, "p->local: %s\n", saddr2str((struct sockaddr *)p->local));
187		plog(ASL_LEVEL_DEBUG, "p->remote: %s\n", saddr2str((struct sockaddr *)p->remote));
188		if (CMPSADDR(local, p->local) == 0
189			&& CMPSADDR(remote, p->remote) == 0){
190			plog(ASL_LEVEL_DEBUG, "matched\n");
191			return p;
192		}
193	}
194
195	plog(ASL_LEVEL_DEBUG, "no match\n");
196
197	return NULL;
198}
199
200static phase1_handle_t *
201sgetph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
202{
203    phase1_handle_t *p = NULL;
204
205	LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
206		if (FSM_STATE_IS_EXPIRED(p->status))
207			continue;
208		if (cmpsaddrwop(local, p->local) == 0
209            && cmpsaddrwop(remote, p->remote) == 0)
210			return p;
211	}
212
213	return NULL;
214}
215
216phase1_handle_t *
217ike_session_getph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
218{
219	phase1_handle_t *p;
220    ike_session_t   *cur_session = NULL;
221
222    if (session)
223        return sgetph1byaddrwop(session, local, remote);
224
225    LIST_FOREACH(cur_session, &ike_session_tree, chain) {
226        if ((p = sgetph1byaddrwop(cur_session, local, remote)) != NULL)
227            return p;
228	}
229
230	return NULL;
231}
232
233/*
234 * search for isakmpsa handler by remote address.
235 * don't use port number to search because this function search
236 * with phase 2's destinaion.
237 */
238phase1_handle_t *
239sike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote)
240{
241	phase1_handle_t *p = NULL;
242
243    LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
244        if (FSM_STATE_IS_EXPIRED(p->status))
245            continue;
246        if (cmpsaddrwop(remote, p->remote) == 0)
247            return p;
248    }
249
250    return NULL;
251}
252
253phase1_handle_t *
254ike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote)
255{
256	phase1_handle_t *p;
257    ike_session_t   *cur_session = NULL;
258
259    if (session)
260        return sike_session_getph1bydstaddrwop(session, remote);
261    else {
262        LIST_FOREACH(cur_session, &ike_session_tree, chain) {
263            if ((p = sike_session_getph1bydstaddrwop(cur_session, remote)) != NULL)
264                return p;
265        }
266    }
267    return NULL;
268}
269
270int
271ike_session_islast_ph1(phase1_handle_t *ph1)
272{
273    phase1_handle_t *p = NULL;
274
275    LIST_FOREACH(p, &ph1->parent_session->ph1tree, ph1ofsession_chain) {
276		if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status))
277			continue;
278		if (CMPSADDR(ph1->remote, p->remote) == 0) {
279			if (p == ph1)
280				continue;
281			return 0;
282		}
283	}
284	return 1;
285}
286
287/*
288 * create new isakmp Phase 1 status record to handle isakmp in Phase1
289 */
290phase1_handle_t *
291ike_session_newph1(unsigned int version)
292{
293	phase1_handle_t *iph1;
294
295	/* create new iph1 */
296	iph1 = racoon_calloc(1, sizeof(*iph1));
297	if (iph1 == NULL)
298		return NULL;
299	iph1->version = version;
300
301#ifdef ENABLE_DPD
302	iph1->dpd_support = 0;
303	iph1->dpd_lastack = 0;
304	iph1->dpd_seq = 0;
305	iph1->dpd_fails = 0;
306    iph1->peer_sent_ike = 0;
307	iph1->dpd_r_u = NULL;
308#endif
309#ifdef ENABLE_VPNCONTROL_PORT
310	iph1->ping_sched = NULL;
311#endif
312	iph1->is_dying = 0;
313    plog(ASL_LEVEL_DEBUG, "*** New Phase 1\n");
314	return iph1;
315}
316
317/*
318 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
319 */
320void
321ike_session_delph1(phase1_handle_t *iph1)
322{
323	if (iph1 == NULL)
324		return;
325
326#ifdef ENABLE_NATT
327	if (iph1->natt_options) {
328		racoon_free(iph1->natt_options);
329		iph1->natt_options = NULL;
330	}
331#endif
332
333#ifdef ENABLE_HYBRID
334	if (iph1->mode_cfg)
335		isakmp_cfg_rmstate(iph1);
336	VPTRINIT(iph1->xauth_awaiting_userinput_msg);
337#endif
338
339#ifdef ENABLE_DPD
340	if (iph1->dpd_r_u)
341		SCHED_KILL(iph1->dpd_r_u);
342#endif
343#ifdef ENABLE_VPNCONTROL_PORT
344	if (iph1->ping_sched)
345		SCHED_KILL(iph1->ping_sched);
346#endif
347
348	if (iph1->remote) {
349		racoon_free(iph1->remote);
350		iph1->remote = NULL;
351	}
352	if (iph1->local) {
353		racoon_free(iph1->local);
354		iph1->local = NULL;
355	}
356
357	if (iph1->approval) {
358		delisakmpsa(iph1->approval);
359		iph1->approval = NULL;
360	}
361
362	sched_scrub_param(iph1);
363    if (iph1->sce)
364        SCHED_KILL(iph1->sce);
365    if (iph1->sce_rekey)
366        SCHED_KILL(iph1->sce_rekey);
367    if (iph1->scr)
368        SCHED_KILL(iph1->scr);
369
370	VPTRINIT(iph1->sendbuf);
371
372	VPTRINIT(iph1->dhpriv);
373	VPTRINIT(iph1->dhpub);
374	VPTRINIT(iph1->dhpub_p);
375	VPTRINIT(iph1->dhgxy);
376	VPTRINIT(iph1->nonce);
377	VPTRINIT(iph1->nonce_p);
378	VPTRINIT(iph1->skeyid);
379	VPTRINIT(iph1->skeyid_d);
380	VPTRINIT(iph1->skeyid_a);
381	VPTRINIT(iph1->skeyid_a_p);
382	VPTRINIT(iph1->skeyid_e);
383    VPTRINIT(iph1->skeyid_e_p);
384	VPTRINIT(iph1->key);
385    VPTRINIT(iph1->key_p);
386	VPTRINIT(iph1->hash);
387	VPTRINIT(iph1->sig);
388	VPTRINIT(iph1->sig_p);
389	oakley_delcert(iph1->cert);
390	iph1->cert = NULL;
391	oakley_delcert(iph1->cert_p);
392	iph1->cert_p = NULL;
393	oakley_delcert(iph1->crl_p);
394	iph1->crl_p = NULL;
395	oakley_delcert(iph1->cr_p);
396	iph1->cr_p = NULL;
397	VPTRINIT(iph1->id);
398	VPTRINIT(iph1->id_p);
399
400	if(iph1->approval != NULL)
401		delisakmpsa(iph1->approval);
402
403	if (iph1->ivm) {
404		oakley_delivm(iph1->ivm);
405		iph1->ivm = NULL;
406	}
407
408	VPTRINIT(iph1->sa);
409	VPTRINIT(iph1->sa_ret);
410
411	if (iph1->rmconf) {
412		release_rmconf(iph1->rmconf);
413		iph1->rmconf = NULL;
414	}
415
416	racoon_free(iph1);
417}
418
419void
420ike_session_flush_all_phase1_for_session(ike_session_t *session, int ignore_estab_or_assert_handles)
421{
422	phase1_handle_t *p, *next;
423
424    LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) {
425        if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) {
426            plog(ASL_LEVEL_DEBUG,
427                 "Skipping Phase 1 %s that's asserted...\n",
428                 isakmp_pindex(&p->index, 0));
429            continue;
430        }
431
432        /* send delete information */
433        if (FSM_STATE_IS_ESTABLISHED(p->status)) {
434            if (ignore_estab_or_assert_handles &&
435                (ike_session_has_negoing_ph2(p->parent_session) || ike_session_has_established_ph2(p->parent_session))) {
436                plog(ASL_LEVEL_DEBUG,
437                     "Skipping Phase 1 %s that's established... because it's needed by children Phase 2s\n",
438                     isakmp_pindex(&p->index, 0));
439                continue;
440            }
441            /* send delete information */
442            plog(ASL_LEVEL_DEBUG,
443                 "Got a Phase 1 %s to flush...\n",
444                 isakmp_pindex(&p->index, 0));
445            isakmp_info_send_d1(p);
446        }
447
448        ike_session_stopped_by_controller(p->parent_session,
449                                          ike_session_stopped_by_flush);
450
451        ike_session_unlink_phase1(p);
452    }
453}
454
455/*
456 * flush isakmp-sa
457 */
458void
459ike_session_flush_all_phase1(int ignore_estab_or_assert_handles)
460{
461    ike_session_t *session = NULL;
462    ike_session_t *next_session = NULL;
463
464	plog(ASL_LEVEL_DEBUG,
465		 "Flushing Phase 1 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
466
467    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
468        ike_session_flush_all_phase1_for_session(session, ignore_estab_or_assert_handles);
469    }
470}
471
472
473
474/*
475 * search ph2handle with policy id.
476 */
477phase2_handle_t *
478ike_session_getph2byspid(u_int32_t spid)
479{
480    ike_session_t *session = NULL;
481    phase2_handle_t *p;
482
483    LIST_FOREACH(session, &ike_session_tree, chain) {
484        LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) {
485            /*
486             * there are ph2handle independent on policy
487             * such like informational exchange.
488             */
489            if (p->spid == spid)
490                return p;
491        }
492    }
493
494	return NULL;
495}
496
497
498/*
499 * search ph2handle with sequence number.
500 * Used by PF_KEY functions to locate the phase2
501 */
502phase2_handle_t *
503ike_session_getph2byseq(u_int32_t seq)
504{
505    ike_session_t *session;
506	phase2_handle_t *p;
507
508    LIST_FOREACH(session, &ike_session_tree, chain) {
509        LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) {
510            if (p->seq == seq)
511                return p;
512        }
513    }
514	return NULL;
515}
516
517/*
518 * search ph2handle with message id.
519 */
520phase2_handle_t *
521ike_session_getph2bymsgid(phase1_handle_t *iph1, u_int32_t msgid)
522{
523	phase2_handle_t *p;
524
525	LIST_FOREACH(p, &iph1->parent_session->ph2tree, ph2ofsession_chain) {
526		if (p->msgid == msgid && !p->is_defunct)
527			return p;
528	}
529
530	return NULL;
531}
532
533phase2_handle_t *
534ike_session_getonlyph2(phase1_handle_t *iph1)
535{
536    phase2_handle_t *only_ph2 = NULL;
537	phase2_handle_t *p = NULL;
538
539	LIST_FOREACH(p, &iph1->bound_ph2tree, ph2ofsession_chain) {
540		if (only_ph2) return NULL;
541        only_ph2 = p;
542	}
543
544	return only_ph2;
545}
546
547phase2_handle_t *
548ike_session_getph2byid(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int32_t spid)
549{
550    ike_session_t *session = NULL;
551    ike_session_t *next_session = NULL;
552    phase2_handle_t *p;
553    phase2_handle_t *next_iph2;
554
555    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
556        LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next_iph2) {
557            if (spid == p->spid &&
558                CMPSADDR(src, p->src) == 0 &&
559                CMPSADDR(dst, p->dst) == 0){
560                /* Sanity check to detect zombie handlers
561                 * XXX Sould be done "somewhere" more interesting,
562                 * because we have lots of getph2byxxxx(), but this one
563                 * is called by pk_recvacquire(), so is the most important.
564                 */
565                if(!FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p->status) &&
566                   p->retry_counter == 0
567                   && p->sce == 0 && p->scr == 0 &&
568                   p->retry_checkph1 == 0){
569                    plog(ASL_LEVEL_DEBUG,
570                         "Zombie ph2 found, expiring it\n");
571                    isakmp_ph2expire(p);
572                }else
573                    return p;
574            }
575        }
576    }
577
578	return NULL;
579}
580
581#ifdef NOT_USED
582phase2_handle_t *
583ike_session_getph2bysaddr(struct sockaddr_storage *src, struct sockaddr_storage *dst)
584{
585    ike_session_t *session;
586	phase2_handle_t *p;
587
588    LIST_FOREACH(session, &ike_session_tree, chain) {
589        LIST_FOREACH(p, &session->ph2tree, chain) {
590            if (cmpsaddrstrict(src, p->src) == 0 &&
591                cmpsaddrstrict(dst, p->dst) == 0)
592                return p;
593        }
594    }
595
596	return NULL;
597}
598#endif /* NOT_USED */
599
600/*
601 * call by pk_recvexpire().
602 */
603phase2_handle_t *
604ike_session_getph2bysaidx(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi)
605{
606    ike_session_t *session;
607	phase2_handle_t *iph2;
608	struct saproto *pr;
609
610    LIST_FOREACH(session, &ike_session_tree, chain) {
611        LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_chain) {
612            if (iph2->proposal == NULL && iph2->approval == NULL)
613                continue;
614            if (iph2->approval != NULL) {
615                for (pr = iph2->approval->head; pr != NULL;
616                     pr = pr->next) {
617                    if (proto_id != pr->proto_id)
618                        break;
619                    if (spi == pr->spi || spi == pr->spi_p)
620                        return iph2;
621                }
622            } else if (iph2->proposal != NULL) {
623                for (pr = iph2->proposal->head; pr != NULL;
624                     pr = pr->next) {
625                    if (proto_id != pr->proto_id)
626                        break;
627                    if (spi == pr->spi)
628                        return iph2;
629                }
630            }
631        }
632    }
633
634	return NULL;
635}
636
637phase2_handle_t *
638ike_session_getph2bysaidx2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi, u_int32_t *opposite_spi)
639{
640    ike_session_t *session;
641	phase2_handle_t *iph2;
642	struct saproto *pr;
643
644    LIST_FOREACH(session, &ike_session_tree, chain) {
645        LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_chain) {
646            if (iph2->proposal == NULL && iph2->approval == NULL)
647                continue;
648            if (iph2->approval != NULL) {
649                for (pr = iph2->approval->head; pr != NULL;
650                     pr = pr->next) {
651                    if (proto_id != pr->proto_id)
652                        break;
653                    if (spi == pr->spi || spi == pr->spi_p) {
654						if (opposite_spi) {
655							*opposite_spi = (spi == pr->spi)? pr->spi_p : pr->spi;
656						}
657                        return iph2;
658					}
659                }
660            } else if (iph2->proposal != NULL) {
661                for (pr = iph2->proposal->head; pr != NULL;
662                     pr = pr->next) {
663                    if (proto_id != pr->proto_id)
664                        break;
665                    if (spi == pr->spi || spi == pr->spi_p) {
666						if (opposite_spi) {
667							*opposite_spi = (spi == pr->spi)? pr->spi_p : pr->spi;
668						}
669                        return iph2;
670					}
671                }
672            }
673        }
674    }
675
676	return NULL;
677}
678
679/*
680 * create new isakmp Phase 2 status record to handle isakmp in Phase2
681 */
682phase2_handle_t *
683ike_session_newph2(unsigned int version, int type)
684{
685	phase2_handle_t *iph2 = NULL;
686
687	/* create new iph2 */
688	iph2 = racoon_calloc(1, sizeof(*iph2));
689	if (iph2 == NULL)
690		return NULL;
691    iph2->version = version;
692    iph2->phase2_type = type;
693	iph2->is_dying = 0;
694
695    plog(ASL_LEVEL_DEBUG, "*** New Phase 2\n");
696	return iph2;
697}
698
699/*
700 * initialize ph2handle
701 * NOTE: don't initialize src/dst.
702 *       SPI in the proposal is cleared.
703 */
704void
705ike_session_initph2(phase2_handle_t *iph2)
706{
707	sched_scrub_param(iph2);
708	iph2->sce = NULL;
709	iph2->scr = NULL;
710
711	VPTRINIT(iph2->sendbuf);
712	VPTRINIT(iph2->msg1);
713
714	/* clear spi, keep variables in the proposal */
715	if (iph2->proposal) {
716		struct saproto *pr;
717		for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
718			pr->spi = 0;
719	}
720
721	/* clear approval */
722	if (iph2->approval) {
723		flushsaprop(iph2->approval);
724		iph2->approval = NULL;
725	}
726
727	/* clear the generated policy */
728	if (iph2->spidx_gen) {
729		delsp_bothdir(iph2->spidx_gen);
730		racoon_free(iph2->spidx_gen);
731		iph2->spidx_gen = NULL;
732	}
733
734	if (iph2->pfsgrp) {
735		oakley_dhgrp_free(iph2->pfsgrp);
736		iph2->pfsgrp = NULL;
737	}
738
739	VPTRINIT(iph2->dhpriv);
740	VPTRINIT(iph2->dhpub);
741	VPTRINIT(iph2->dhpub_p);
742	VPTRINIT(iph2->dhgxy);
743	VPTRINIT(iph2->id);
744	VPTRINIT(iph2->id_p);
745	VPTRINIT(iph2->nonce);
746	VPTRINIT(iph2->nonce_p);
747	VPTRINIT(iph2->sa);
748	VPTRINIT(iph2->sa_ret);
749
750	if (iph2->ivm) {
751		oakley_delivm(iph2->ivm);
752		iph2->ivm = NULL;
753	}
754}
755
756/*
757 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
758 */
759void
760ike_session_delph2(phase2_handle_t *iph2)
761{
762	ike_session_initph2(iph2);
763
764	if (iph2->src) {
765		racoon_free(iph2->src);
766		iph2->src = NULL;
767	}
768	if (iph2->dst) {
769		racoon_free(iph2->dst);
770		iph2->dst = NULL;
771	}
772	if (iph2->src_id) {
773        racoon_free(iph2->src_id);
774        iph2->src_id = NULL;
775	}
776	if (iph2->dst_id) {
777        racoon_free(iph2->dst_id);
778        iph2->dst_id = NULL;
779	}
780
781	if (iph2->proposal) {
782		flushsaprop(iph2->proposal);
783		iph2->proposal = NULL;
784	}
785
786	if (iph2->sainfo) {
787		release_sainfo(iph2->sainfo);
788		iph2->sainfo = NULL;
789	}
790    VPTRINIT(iph2->id);
791    VPTRINIT(iph2->id_p);
792	VPTRINIT(iph2->ext_nat_id);
793	VPTRINIT(iph2->ext_nat_id_p);
794
795    if (iph2->sce)
796        SCHED_KILL(iph2->sce);
797    if (iph2->scr)
798        SCHED_KILL(iph2->scr);
799
800	racoon_free(iph2);
801}
802
803void
804ike_session_flush_all_phase2_for_session(ike_session_t *session, int ignore_estab_or_assert_handles)
805{
806    phase2_handle_t *p = NULL;
807    phase2_handle_t *next = NULL;
808    LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next) {
809        if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) {
810            continue;
811        }
812        if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) {
813            plog(ASL_LEVEL_DEBUG,
814                 "skipping phase2 handle that's asserted...\n");
815            continue;
816        }
817        if (FSM_STATE_IS_ESTABLISHED(p->status)){
818            if (ignore_estab_or_assert_handles) {
819                plog(ASL_LEVEL_DEBUG,
820                     "skipping ph2 handler that's established...\n");
821                continue;
822            }
823            /* send delete information */
824            plog(ASL_LEVEL_DEBUG,
825                 "got an established ph2 handler to flush...\n");
826            isakmp_info_send_d2(p);
827        }else{
828            plog(ASL_LEVEL_DEBUG,
829                 "got a ph2 handler to flush (state %d)\n", p->status);
830        }
831
832        ike_session_stopped_by_controller(p->parent_session,
833                                          ike_session_stopped_by_flush);
834        delete_spd(p);
835        ike_session_unlink_phase2(p);
836    }
837}
838
839void
840ike_session_flush_all_phase2(int ignore_estab_or_assert_handles)
841{
842    ike_session_t *session = NULL;
843    ike_session_t *next_session = NULL;
844
845	plog(ASL_LEVEL_DEBUG,
846		 "flushing ph2 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
847
848    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
849        ike_session_flush_all_phase2_for_session(session, ignore_estab_or_assert_handles);
850    }
851}
852
853/*
854 * Delete all Phase 2 handlers for this src/dst/proto.  This
855 * is used during INITIAL-CONTACT processing (so no need to
856 * send a message to the peer).
857 */
858//%%%%%%%%%%%%%%%%%%% make this smarter - find session using addresses ????
859void
860ike_session_deleteallph2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id)
861{
862    ike_session_t *session = NULL;
863    ike_session_t *next_session = NULL;
864    phase2_handle_t *iph2 = NULL;
865    phase2_handle_t *next_iph2 = NULL;
866	struct saproto *pr;
867
868    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
869        LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
870            if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
871                continue;
872            }
873            if (iph2->proposal == NULL && iph2->approval == NULL)
874                continue;
875            if (cmpsaddrwop(src, iph2->src) != 0 ||
876                cmpsaddrwop(dst, iph2->dst) != 0) {
877                continue;
878            }
879            if (iph2->approval != NULL) {
880                for (pr = iph2->approval->head; pr != NULL;
881                     pr = pr->next) {
882                    if (proto_id == pr->proto_id)
883                        goto zap_it;
884                }
885            } else if (iph2->proposal != NULL) {
886                for (pr = iph2->proposal->head; pr != NULL;
887                     pr = pr->next) {
888                    if (proto_id == pr->proto_id)
889                        goto zap_it;
890                }
891            }
892            continue;
893        zap_it:
894            plog(ASL_LEVEL_DEBUG,
895                 "deleteallph2: got a ph2 handler...\n");
896            if (FSM_STATE_IS_ESTABLISHED(iph2->status))
897                isakmp_info_send_d2(iph2);
898            ike_session_stopped_by_controller(iph2->parent_session,
899                                              ike_session_stopped_by_flush);
900            ike_session_unlink_phase2(iph2);
901        }
902    }
903}
904
905/*
906 * Delete all Phase 1 handlers for this src/dst.
907 */
908void
909ike_session_deleteallph1(struct sockaddr_storage *src, struct sockaddr_storage *dst)
910{
911    ike_session_t *session = NULL;
912    ike_session_t *next_session = NULL;
913    phase1_handle_t *iph1 = NULL;
914    phase1_handle_t *next_iph1 = NULL;
915
916    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
917        LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) {
918            if (cmpsaddrwop(src, iph1->local) != 0 ||
919                cmpsaddrwop(dst, iph1->remote) != 0) {
920                continue;
921            }
922            plog(ASL_LEVEL_DEBUG,
923                 "deleteallph1: got a ph1 handler...\n");
924            if (FSM_STATE_IS_ESTABLISHED(iph1->status))
925                isakmp_info_send_d1(iph1);
926
927            ike_session_stopped_by_controller(iph1->parent_session, ike_session_stopped_by_flush);
928            ike_session_unlink_phase1(iph1);
929        }
930    }
931}
932
933
934/* %%% management contacted list */
935/*
936 * search contacted list.
937 */
938struct contacted *
939ike_session_getcontacted(remote)
940struct sockaddr_storage *remote;
941{
942	struct contacted *p;
943
944	LIST_FOREACH(p, &ctdtree, chain) {
945		if (cmpsaddrstrict(remote, p->remote) == 0)
946			return p;
947	}
948
949	return NULL;
950}
951
952/*
953 * create new isakmp Phase 2 status record to handle isakmp in Phase2
954 */
955int
956ike_session_inscontacted(remote)
957struct sockaddr_storage *remote;
958{
959	struct contacted *new;
960
961	/* create new iph2 */
962	new = racoon_calloc(1, sizeof(*new));
963	if (new == NULL)
964		return -1;
965
966	new->remote = dupsaddr(remote);
967	if (new->remote == NULL) {
968		plog(ASL_LEVEL_ERR,
969             "failed to allocate buffer.\n");
970		racoon_free(new);
971		return -1;
972	}
973
974	LIST_INSERT_HEAD(&ctdtree, new, chain);
975
976	return 0;
977}
978
979
980void
981ike_session_clear_contacted()
982{
983	struct contacted *c, *next;
984	LIST_FOREACH_SAFE(c, &ctdtree, chain, next) {
985		LIST_REMOVE(c, chain);
986		racoon_free(c->remote);
987		racoon_free(c);
988	}
989}
990
991void
992ike_session_initctdtree()
993{
994	LIST_INIT(&ctdtree);
995}
996
997time_t
998ike_session_get_exp_retx_interval (int num_retries, int fixed_retry_interval)
999{
1000	// first 3 retries aren't exponential
1001	if (num_retries <= 3) {
1002		return (time_t)fixed_retry_interval;
1003	} else {
1004		return (time_t)(num_retries * fixed_retry_interval);
1005	}
1006}
1007
1008/*
1009 * check the response has been sent to the peer.  when not, simply reply
1010 * the buffered packet to the peer.
1011 * OUT:
1012 *	 0:	the packet is received at the first time.
1013 *	 1:	the packet was processed before.
1014 *	 2:	the packet was processed before, but the address mismatches.
1015 *	-1:	error happened.
1016 */
1017int
1018ike_session_check_recvdpkt(remote, local, rbuf)
1019struct sockaddr_storage *remote, *local;
1020vchar_t *rbuf;
1021{
1022	vchar_t *hash;
1023	struct recvdpkt *r;
1024	time_t t, d;
1025	int len, s;
1026
1027	/* set current time */
1028	t = time(NULL);
1029
1030	hash = eay_md5_one(rbuf);
1031	if (!hash) {
1032		plog(ASL_LEVEL_ERR,
1033             "failed to allocate buffer.\n");
1034		return -1;
1035	}
1036
1037	LIST_FOREACH(r, &rcptree, chain) {
1038		if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
1039			break;
1040	}
1041	vfree(hash);
1042
1043	/* this is the first time to receive the packet */
1044	if (r == NULL)
1045		return 0;
1046
1047	/*
1048	 * the packet was processed before, but the remote address mismatches.
1049     * ignore the port to accomodate port changes (e.g. floating).
1050	 */
1051	if (cmpsaddrwop(remote, r->remote) != 0) {
1052        return 2;
1053    }
1054
1055	/*
1056	 * it should not check the local address because the packet
1057	 * may arrive at other interface.
1058	 */
1059
1060	/* check the previous time to send */
1061	if (t - r->time_send < 1) {
1062		plog(ASL_LEVEL_WARNING,
1063             "the packet retransmitted in a short time from %s\n",
1064             saddr2str((struct sockaddr *)remote));
1065		/*XXX should it be error ? */
1066	}
1067
1068	/* select the socket to be sent */
1069	s = getsockmyaddr((struct sockaddr *)r->local);
1070	if (s == -1)
1071		return -1;
1072
1073	// don't send if we recently sent a response.
1074	if (r->time_send && t > r->time_send) {
1075		d = t - r->time_send;
1076		if (d  < r->retry_interval) {
1077			plog(ASL_LEVEL_ERR, "already responded within the past %ld secs\n", d);
1078			return 1;
1079		}
1080	}
1081
1082#ifdef ENABLE_FRAG
1083	if (r->frag_flags && r->sendbuf->l > ISAKMP_FRAG_MAXLEN) {
1084		/* resend the packet if needed */
1085		plog(ASL_LEVEL_ERR, "!!! retransmitting frags\n");
1086		len = sendfragsfromto(s, r->sendbuf,
1087							  r->local, r->remote, lcconf->count_persend,
1088							  r->frag_flags);
1089	} else {
1090		plog(ASL_LEVEL_ERR, "!!! skipped retransmitting frags: frag_flags %x, r->sendbuf->l %zu, max %d\n", r->frag_flags, r->sendbuf->l, ISAKMP_FRAG_MAXLEN);
1091		/* resend the packet if needed */
1092		len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
1093						 r->local, r->remote, lcconf->count_persend);
1094	}
1095#else
1096	/* resend the packet if needed */
1097	len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
1098                     r->local, r->remote, lcconf->count_persend);
1099#endif
1100	if (len == -1) {
1101		plog(ASL_LEVEL_ERR, "sendfromto failed\n");
1102		return -1;
1103	}
1104
1105	/* check the retry counter */
1106	r->retry_counter--;
1107	if (r->retry_counter <= 0) {
1108		ike_session_rem_recvdpkt(r);
1109		ike_session_del_recvdpkt(r);
1110		plog(ASL_LEVEL_DEBUG,
1111             "deleted the retransmission packet to %s.\n",
1112             saddr2str((struct sockaddr *)remote));
1113	} else {
1114		r->time_send = t;
1115		r->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - r->retry_counter),
1116												  lcconf->retry_interval);
1117	}
1118
1119	return 1;
1120}
1121
1122/*
1123 * adding a hash of received packet into the received list.
1124 */
1125int
1126ike_session_add_recvdpkt(remote, local, sbuf, rbuf, non_esp, frag_flags)
1127struct sockaddr_storage *remote, *local;
1128vchar_t *sbuf, *rbuf;
1129size_t non_esp;
1130u_int32_t frag_flags;
1131{
1132	struct recvdpkt *new = NULL;
1133
1134	if (lcconf->retry_counter == 0) {
1135		/* no need to add it */
1136		return 0;
1137	}
1138
1139	new = racoon_calloc(1, sizeof(*new));
1140	if (!new) {
1141		plog(ASL_LEVEL_ERR,
1142             "failed to allocate buffer.\n");
1143		return -1;
1144	}
1145
1146	new->hash = eay_md5_one(rbuf);
1147	if (!new->hash) {
1148		plog(ASL_LEVEL_ERR,
1149             "failed to allocate buffer.\n");
1150		ike_session_del_recvdpkt(new);
1151		return -1;
1152	}
1153	new->remote = dupsaddr(remote);
1154	if (new->remote == NULL) {
1155		plog(ASL_LEVEL_ERR,
1156             "failed to allocate buffer.\n");
1157		ike_session_del_recvdpkt(new);
1158		return -1;
1159	}
1160	new->local = dupsaddr(local);
1161	if (new->local == NULL) {
1162		plog(ASL_LEVEL_ERR,
1163             "failed to allocate buffer.\n");
1164		ike_session_del_recvdpkt(new);
1165		return -1;
1166	}
1167
1168	if (non_esp) {
1169		plog (ASL_LEVEL_DEBUG, "Adding NON-ESP marker\n");
1170
1171        /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
1172         must added just before the packet itself. For this we must
1173         allocate a new buffer and release it at the end. */
1174        if ((new->sendbuf = vmalloc (sbuf->l + non_esp)) == NULL) {
1175            plog(ASL_LEVEL_ERR,
1176                 "failed to allocate extra buf for non-esp\n");
1177            ike_session_del_recvdpkt(new);
1178            return -1;
1179        }
1180        *ALIGNED_CAST(u_int32_t *)new->sendbuf->v = 0;
1181        memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l);
1182    } else {
1183        new->sendbuf = vdup(sbuf);
1184        if (new->sendbuf == NULL) {
1185            plog(ASL_LEVEL_ERR,
1186                 "failed to allocate buffer.\n");
1187            ike_session_del_recvdpkt(new);
1188            return -1;
1189        }
1190    }
1191
1192	new->retry_counter = lcconf->retry_counter;
1193	new->time_send = 0;
1194	new->created = time(NULL);
1195#ifdef ENABLE_FRAG
1196	if (frag_flags) {
1197		new->frag_flags = frag_flags;
1198	}
1199#endif
1200	new->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - new->retry_counter),
1201												lcconf->retry_interval);
1202
1203	LIST_INSERT_HEAD(&rcptree, new, chain);
1204
1205	return 0;
1206}
1207
1208void
1209ike_session_del_recvdpkt(r)
1210struct recvdpkt *r;
1211{
1212	if (r->remote)
1213		racoon_free(r->remote);
1214	if (r->local)
1215		racoon_free(r->local);
1216	if (r->hash)
1217		vfree(r->hash);
1218	if (r->sendbuf)
1219		vfree(r->sendbuf);
1220	racoon_free(r);
1221}
1222
1223void
1224ike_session_rem_recvdpkt(r)
1225struct recvdpkt *r;
1226{
1227	LIST_REMOVE(r, chain);
1228}
1229
1230void
1231sweep_recvdpkt(dummy)
1232void *dummy;
1233{
1234	struct recvdpkt *r, *next;
1235	time_t t, lt;
1236
1237	/* set current time */
1238	t = time(NULL);
1239
1240	/* set the lifetime of the retransmission */
1241	lt = lcconf->retry_counter * lcconf->retry_interval;
1242
1243	LIST_FOREACH_SAFE(r, &rcptree, chain, next) {
1244		if (t - r->created > lt) {
1245			ike_session_rem_recvdpkt(r);
1246			ike_session_del_recvdpkt(r);
1247		}
1248	}
1249
1250	sched_new(lt, sweep_recvdpkt, &rcptree);
1251}
1252
1253void
1254ike_session_clear_recvdpkt()
1255{
1256	struct recvdpkt *r, *next;
1257
1258	LIST_FOREACH_SAFE(r, &rcptree, chain, next) {
1259		ike_session_rem_recvdpkt(r);
1260		ike_session_del_recvdpkt(r);
1261	}
1262	sched_scrub_param(&rcptree);
1263}
1264
1265void
1266ike_session_init_recvdpkt()
1267{
1268	time_t lt = lcconf->retry_counter * lcconf->retry_interval;
1269
1270	LIST_INIT(&rcptree);
1271
1272	sched_new(lt, sweep_recvdpkt, &rcptree);
1273}
1274
1275#ifdef NOT_USED
1276#ifdef ENABLE_HYBRID
1277/*
1278 * Returns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
1279 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
1280 */
1281int
1282exclude_cfg_addr(const struct sockaddr_storage *addr)
1283{
1284    ike_session_t *session;
1285	phase1_handle_t *p;
1286	struct sockaddr_in *sin;
1287
1288    LIST_FOREACH(session, &ike_session_tree, chain) {
1289        LIST_FOREACH(p, &session->ph1tree, chain) {
1290            if ((p->mode_cfg != NULL) &&
1291                (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
1292                (addr->ss_family == AF_INET)) {
1293                sin = (struct sockaddr_in *)addr;
1294                if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
1295                    return 0;
1296            }
1297        }
1298    }
1299
1300	return 1;
1301}
1302#endif
1303#endif /* NOT_USED */
1304
1305int
1306ike_session_expire_session(ike_session_t *session)
1307{
1308	int    found = 0;
1309	phase1_handle_t *p;
1310	phase1_handle_t *next;
1311	phase2_handle_t *p2;
1312
1313    if (session == NULL)
1314        return 0;
1315
1316    LIST_FOREACH(p2, &session->ph2tree, ph2ofsession_chain) {
1317        if (p2->is_dying || FSM_STATE_IS_EXPIRED(p2->status)) {
1318            continue;
1319        }
1320
1321        // Don't send a delete, since the ph1 implies the removal of ph2s
1322        isakmp_ph2expire(p2);
1323        found++;
1324    }
1325
1326    LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) {
1327        if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) {
1328            continue;
1329        }
1330
1331        ike_session_purge_ph2s_by_ph1(p);
1332        if (FSM_STATE_IS_ESTABLISHED(p->status))
1333            isakmp_info_send_d1(p);
1334        isakmp_ph1expire(p);
1335        found++;
1336    }
1337
1338	return found;
1339}
1340
1341#ifdef ENABLE_HYBRID
1342int
1343ike_session_purgephXbydstaddrwop(struct sockaddr_storage *remote)
1344{
1345	int    found = 0;
1346    ike_session_t *session = NULL;
1347    ike_session_t *next_session = NULL;
1348	phase1_handle_t *p;
1349	phase2_handle_t *p2;
1350
1351    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
1352        LIST_FOREACH(p2, &session->ph2tree, ph2ofsession_chain) {
1353		if (p2->is_dying || FSM_STATE_IS_EXPIRED(p2->status)) {
1354			continue;
1355		}
1356            if (cmpsaddrwop(remote, p2->dst) == 0) {
1357                plog(ASL_LEVEL_DEBUG,
1358                     "in %s... purging Phase 2 structures\n", __FUNCTION__);
1359                if (FSM_STATE_IS_ESTABLISHED(p2->status))
1360                    isakmp_info_send_d2(p2);
1361                isakmp_ph2expire(p2);
1362                found++;
1363            }
1364        }
1365
1366        LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
1367		if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) {
1368			continue;
1369		}
1370            if (cmpsaddrwop(remote, p->remote) == 0) {
1371                plog(ASL_LEVEL_DEBUG,
1372                     "in %s... purging Phase 1 and related Phase 2 structures\n", __FUNCTION__);
1373                ike_session_purge_ph2s_by_ph1(p);
1374                if (FSM_STATE_IS_ESTABLISHED(p->status))
1375                    isakmp_info_send_d1(p);
1376                isakmp_ph1expire(p);
1377                found++;
1378            }
1379        }
1380    }
1381
1382	return found;
1383}
1384
1385void
1386ike_session_purgephXbyspid(u_int32_t spid, int del_boundph1)
1387{
1388    ike_session_t *session = NULL;
1389    ike_session_t *next_session = NULL;
1390    phase2_handle_t *iph2 = NULL;
1391    phase2_handle_t *next_iph2 = NULL;
1392    phase1_handle_t *iph1 = NULL;
1393    phase1_handle_t *next_iph1 = NULL;
1394
1395    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
1396        // do ph2's first... we need the ph1s for notifications
1397        LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
1398            if (spid == iph2->spid) {
1399                if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
1400                    continue;
1401                }
1402                if (FSM_STATE_IS_ESTABLISHED(iph2->status)) {
1403                    isakmp_info_send_d2(iph2);
1404                }
1405                ike_session_stopped_by_controller(iph2->parent_session,
1406                                                  ike_session_stopped_by_flush);
1407                isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
1408            }
1409        }
1410
1411        // do the ph1s last.   %%%%%%%%%%%%%%%%%% re-organize this - check del_boundph1 first
1412        LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
1413            if (spid == iph2->spid) {
1414                if (del_boundph1 && iph2->parent_session) {
1415                    LIST_FOREACH_SAFE(iph1, &iph2->parent_session->ph1tree, ph1ofsession_chain, next_iph1) {
1416                        if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) {
1417                            continue;
1418                        }
1419                        if (FSM_STATE_IS_ESTABLISHED(iph1->status)) {
1420                            isakmp_info_send_d1(iph1);
1421                        }
1422                        isakmp_ph1expire(iph1);
1423                    }
1424                }
1425            }
1426        }
1427    }
1428}
1429
1430#endif
1431
1432#ifdef ENABLE_DPD
1433int
1434ike_session_ph1_force_dpd (struct sockaddr_storage *remote)
1435{
1436    int status = -1;
1437    ike_session_t *session = NULL;
1438    phase1_handle_t *p = NULL;
1439
1440    LIST_FOREACH(session, &ike_session_tree, chain) {
1441        LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
1442            if (cmpsaddrwop(remote, p->remote) == 0) {
1443                if (FSM_STATE_IS_ESTABLISHED(p->status) &&
1444                    !p->is_dying &&
1445                    p->dpd_support &&
1446                    p->rmconf->dpd_interval) {
1447                    if(!p->dpd_fails) {
1448                        isakmp_info_send_r_u(p);
1449                        status = 0;
1450                    } else {
1451                        plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (dpd already in progress).\n");
1452                    }
1453                    if (p->parent_session) {
1454                        p->parent_session->controller_awaiting_peer_resp = 1;
1455                    }
1456                } else {
1457                    plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
1458                         p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval);
1459                }
1460            }
1461        }
1462    }
1463
1464	return status;
1465}
1466#endif
1467
1468void
1469sweep_sleepwake(void)
1470{
1471    ike_session_t   *session = NULL;
1472    ike_session_t   *next_session = NULL;
1473    phase2_handle_t *iph2 = NULL;
1474    phase2_handle_t *next_iph2 = NULL;
1475    phase1_handle_t *iph1 = NULL;
1476    phase1_handle_t *next_iph1 = NULL;
1477
1478    LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
1479        // do the ph1s.
1480        LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) {
1481            if (iph1->parent_session && iph1->parent_session->is_asserted) {
1482                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's been asserted.\n",
1483                     isakmp_pindex(&iph1->index, 0));
1484                continue;
1485            }
1486            if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) {
1487                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's already expired.\n",
1488                     isakmp_pindex(&iph1->index, 0));
1489                continue;
1490            }
1491            if (iph1->sce) {
1492                time_t xtime;
1493                if (sched_get_time(iph1->sce, &xtime)) {
1494                    if (xtime <= swept_at) {
1495                        SCHED_KILL(iph1->sce);
1496                        SCHED_KILL(iph1->sce_rekey);
1497                        iph1->is_dying = 1;
1498                        fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
1499                        ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1
1500                        iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1501                        plog(ASL_LEVEL_DEBUG, "Phase 1 %s expired while sleeping: quick deletion.\n",
1502                             isakmp_pindex(&iph1->index, 0));
1503                    }
1504                }
1505            }
1506            if (iph1->sce_rekey) {
1507                time_t xtime;
1508                if (sched_get_time(iph1->sce_rekey, &xtime)) {
1509                    if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) {
1510                        SCHED_KILL(iph1->sce_rekey);
1511                    }
1512                }
1513            }
1514            if (iph1->scr) {
1515                time_t xtime;
1516                if (sched_get_time(iph1->scr, &xtime)) {
1517                    if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) {
1518                        SCHED_KILL(iph1->scr);
1519                    }
1520                }
1521            }
1522    #ifdef ENABLE_DPD
1523            if (iph1->dpd_r_u) {
1524                time_t xtime;
1525                if (sched_get_time(iph1->dpd_r_u, &xtime)) {
1526                    if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) {
1527                        SCHED_KILL(iph1->dpd_r_u);
1528                    }
1529                }
1530            }
1531    #endif
1532        }
1533
1534        // do ph2's next
1535        LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
1536            if (iph2->parent_session && iph2->parent_session->is_asserted) {
1537                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's been asserted.\n");
1538                continue;
1539            }
1540            if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
1541                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's already expired.\n");
1542                continue;
1543            }
1544            if (iph2->sce) {
1545                time_t xtime;
1546                if (sched_get_time(iph2->sce, &xtime)) {
1547                    if (xtime <= swept_at) {
1548                        fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
1549                        iph2->is_dying = 1;
1550                        isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
1551                        ike_session_stopped_by_controller(iph2->parent_session,
1552                                                      ike_session_stopped_by_sleepwake);
1553                        plog(ASL_LEVEL_DEBUG, "Phase 2 expired while sleeping: quick deletion.\n");
1554                    }
1555                }
1556            }
1557            if (iph2->scr) {
1558                time_t xtime;
1559                if (sched_get_time(iph2->scr, &xtime)) {
1560                    if (FSM_STATE_IS_EXPIRED(iph2->status) || xtime <= swept_at) {
1561                        SCHED_KILL(iph2->scr);
1562                    }
1563                }
1564            }
1565        }
1566    }
1567    //%%%%%%%%%%%%%%% fix this
1568	// do the ike_session last
1569	ike_session_sweep_sleepwake();
1570}
1571