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