1 /* $NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu Exp $ */
3 /* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
58 #include "grabmyaddr.h"
59 #include "algorithm.h"
60 #include "crypto_openssl.h"
63 #include "isakmp_var.h"
67 #include "isakmp_xauth.h"
68 #include "isakmp_cfg.h"
70 #include "isakmp_inf.h"
72 #include "remoteconf.h"
73 #include "localconf.h"
76 #include "nattraversal.h"
77 #include "ike_session.h"
84 #include "power_mgmt.h"
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
;
91 static void del_recvdpkt
__P((struct recvdpkt
*));
92 static void rem_recvdpkt
__P((struct recvdpkt
*));
93 static void sweep_recvdpkt
__P((void *));
96 * functions about management of the isakmp status table
98 /* %%% management phase 1 handler */
100 * search for isakmpsa handler with isakmp index.
103 extern caddr_t
val2str(const char *, size_t);
111 LIST_FOREACH(p
, &ph1tree
, chain
) {
112 if (p
->status
== PHASE1ST_EXPIRED
)
114 if (memcmp(&p
->index
, index
, sizeof(*index
)) == 0)
122 * search for isakmp handler by i_ck in index.
125 getph1byindex0(index
)
130 LIST_FOREACH(p
, &ph1tree
, chain
) {
131 if (p
->status
== PHASE1ST_EXPIRED
)
133 if (memcmp(&p
->index
, index
, sizeof(cookie_t
)) == 0)
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.
146 getph1byaddr(local
, remote
)
147 struct sockaddr
*local
, *remote
;
151 plog(LLV_DEBUG2
, LOCATION
, NULL
, "getph1byaddr: start\n");
152 plog(LLV_DEBUG2
, LOCATION
, NULL
, "local: %s\n", saddr2str(local
));
153 plog(LLV_DEBUG2
, LOCATION
, NULL
, "remote: %s\n", saddr2str(remote
));
155 LIST_FOREACH(p
, &ph1tree
, chain
) {
156 if (p
->status
== PHASE1ST_EXPIRED
)
158 plog(LLV_DEBUG2
, LOCATION
, NULL
, "p->local: %s\n", saddr2str(p
->local
));
159 plog(LLV_DEBUG2
, LOCATION
, NULL
, "p->remote: %s\n", saddr2str(p
->remote
));
160 if (CMPSADDR(local
, p
->local
) == 0
161 && CMPSADDR(remote
, p
->remote
) == 0){
162 plog(LLV_DEBUG2
, LOCATION
, NULL
, "matched\n");
167 plog(LLV_DEBUG2
, LOCATION
, NULL
, "no match\n");
173 getph1byaddrwop(local
, remote
)
174 struct sockaddr
*local
, *remote
;
178 LIST_FOREACH(p
, &ph1tree
, chain
) {
179 if (p
->status
== PHASE1ST_EXPIRED
)
181 if (cmpsaddrwop(local
, p
->local
) == 0
182 && cmpsaddrwop(remote
, p
->remote
) == 0)
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.
195 getph1bydstaddrwop(remote
)
196 struct sockaddr
*remote
;
200 LIST_FOREACH(p
, &ph1tree
, chain
) {
201 if (p
->status
== PHASE1ST_EXPIRED
)
203 if (cmpsaddrwop(remote
, p
->remote
) == 0)
212 struct ph1handle
*ph1
;
216 LIST_FOREACH(p
, &ph1tree
, chain
) {
217 if (p
->is_dying
|| p
->status
== PHASE1ST_EXPIRED
)
219 if (CMPSADDR(ph1
->remote
, p
->remote
) == 0) {
234 struct ph1handle
*iph1
;
239 /* get length of buffer */
240 LIST_FOREACH(iph1
, &ph1tree
, chain
)
243 buf
= vmalloc(cnt
* sizeof(struct ph1dump
));
245 plog(LLV_ERROR
, LOCATION
, NULL
,
246 "failed to get buffer\n");
249 pd
= (struct ph1dump
*)buf
->v
;
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(iph1
->remote
));
256 memcpy(&pd
->local
, iph1
->local
, sysdep_sa_len(iph1
->local
));
257 pd
->version
= iph1
->version
;
258 pd
->etype
= iph1
->etype
;
259 pd
->created
= iph1
->created
;
260 pd
->ph2cnt
= iph1
->ph2cnt
;
268 * create new isakmp Phase 1 status record to handle isakmp in Phase1
273 struct ph1handle
*iph1
;
275 /* create new iph1 */
276 iph1
= racoon_calloc(1, sizeof(*iph1
));
280 iph1
->status
= PHASE1ST_SPAWN
;
283 iph1
->dpd_support
= 0;
284 iph1
->dpd_lastack
= 0;
287 iph1
->peer_sent_ike
= 0;
288 iph1
->dpd_r_u
= NULL
;
290 #ifdef ENABLE_VPNCONTROL_PORT
291 iph1
->ping_sched
= NULL
;
298 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
302 struct ph1handle
*iph1
;
307 /* SA down shell script hook */
308 script_hook(iph1
, SCRIPT_PHASE1_DOWN
);
310 EVT_PUSH(iph1
->local
, iph1
->remote
, EVTT_PHASE1_DOWN
, NULL
);
313 if (iph1
->natt_options
) {
314 racoon_free(iph1
->natt_options
);
315 iph1
->natt_options
= NULL
;
321 isakmp_cfg_rmstate(iph1
);
322 VPTRINIT(iph1
->xauth_awaiting_userinput_msg
);
326 if (iph1
->dpd_r_u
!= NULL
)
327 SCHED_KILL(iph1
->dpd_r_u
);
329 #ifdef ENABLE_VPNCONTROL_PORT
330 if (iph1
->ping_sched
!= NULL
)
331 SCHED_KILL(iph1
->ping_sched
);
335 racoon_free(iph1
->remote
);
339 racoon_free(iph1
->local
);
343 if (iph1
->approval
) {
344 delisakmpsa(iph1
->approval
);
345 iph1
->approval
= NULL
;
348 VPTRINIT(iph1
->authstr
);
350 sched_scrub_param(iph1
);
352 iph1
->sce_rekey
= NULL
;
355 VPTRINIT(iph1
->sendbuf
);
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
);
368 VPTRINIT(iph1
->hash
);
370 VPTRINIT(iph1
->sig_p
);
371 oakley_delcert(iph1
->cert
);
373 oakley_delcert(iph1
->cert_p
);
375 oakley_delcert(iph1
->crl_p
);
377 oakley_delcert(iph1
->cr_p
);
380 VPTRINIT(iph1
->id_p
);
382 if(iph1
->approval
!= NULL
)
383 delisakmpsa(iph1
->approval
);
386 oakley_delivm(iph1
->ivm
);
391 VPTRINIT(iph1
->sa_ret
);
394 VPTRINIT(iph1
->gi_i
);
395 VPTRINIT(iph1
->gi_r
);
397 gssapi_free_state(iph1
);
400 if (iph1
->parent_session
) {
401 ike_session_unlink_ph1_from_session(iph1
);
404 unlink_rmconf_from_ph1(iph1
->rmconf
);
412 * create new isakmp Phase 1 status record to handle isakmp in Phase1
416 struct ph1handle
*iph1
;
419 if (iph1
->remote
== NULL
) {
420 plog(LLV_ERROR
, LOCATION
, NULL
,
421 "invalid isakmp SA handler. no remote address.\n");
424 LIST_INSERT_HEAD(&ph1tree
, iph1
, chain
);
431 struct ph1handle
*iph1
;
433 LIST_REMOVE(iph1
, chain
);
440 flushph1(int ignore_estab_or_assert_handles
)
442 struct ph1handle
*p
, *next
;
444 plog(LLV_DEBUG2
, LOCATION
, NULL
,
445 "flushing ph1 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles
);
447 for (p
= LIST_FIRST(&ph1tree
); p
; p
= next
) {
448 next
= LIST_NEXT(p
, chain
);
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));
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));
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
);
473 ike_session_stopped_by_controller(p
->parent_session
,
474 ike_session_stopped_by_flush
);
486 /* %%% management phase 2 handler */
488 * search ph2handle with policy id.
496 LIST_FOREACH(p
, &ph2tree
, chain
) {
498 * there are ph2handle independent on policy
499 * such like informational exchange.
509 * search ph2handle with sequence number.
517 LIST_FOREACH(p
, &ph2tree
, chain
) {
526 * search ph2handle with message id.
529 getph2bymsgid(iph1
, msgid
)
530 struct ph1handle
*iph1
;
535 LIST_FOREACH(p
, &ph2tree
, chain
) {
536 if (p
->msgid
== msgid
)
544 getph2byid(src
, dst
, spid
)
545 struct sockaddr
*src
, *dst
;
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.
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");
574 getph2bysaddr(src
, dst
)
575 struct sockaddr
*src
, *dst
;
579 LIST_FOREACH(p
, &ph2tree
, chain
) {
580 if (cmpsaddrstrict(src
, p
->src
) == 0 &&
581 cmpsaddrstrict(dst
, p
->dst
) == 0)
589 * call by pk_recvexpire().
592 getph2bysaidx(src
, dst
, proto_id
, spi
)
593 struct sockaddr
*src
, *dst
;
597 struct ph2handle
*iph2
;
600 LIST_FOREACH(iph2
, &ph2tree
, chain
) {
601 if (iph2
->proposal
== NULL
&& iph2
->approval
== NULL
)
603 if (iph2
->approval
!= NULL
) {
604 for (pr
= iph2
->approval
->head
; pr
!= NULL
;
606 if (proto_id
!= pr
->proto_id
)
608 if (spi
== pr
->spi
|| spi
== pr
->spi_p
)
611 } else if (iph2
->proposal
!= NULL
) {
612 for (pr
= iph2
->proposal
->head
; pr
!= NULL
;
614 if (proto_id
!= pr
->proto_id
)
626 * create new isakmp Phase 2 status record to handle isakmp in Phase2
631 struct ph2handle
*iph2
= NULL
;
633 /* create new iph2 */
634 iph2
= racoon_calloc(1, sizeof(*iph2
));
638 iph2
->status
= PHASE1ST_SPAWN
;
645 * initialize ph2handle
646 * NOTE: don't initialize src/dst.
647 * SPI in the proposal is cleared.
651 struct ph2handle
*iph2
;
653 sched_scrub_param(iph2
);
657 VPTRINIT(iph2
->sendbuf
);
658 VPTRINIT(iph2
->msg1
);
660 /* clear spi, keep variables in the proposal */
661 if (iph2
->proposal
) {
663 for (pr
= iph2
->proposal
->head
; pr
!= NULL
; pr
= pr
->next
)
668 if (iph2
->approval
) {
669 flushsaprop(iph2
->approval
);
670 iph2
->approval
= NULL
;
673 /* clear the generated policy */
674 if (iph2
->spidx_gen
) {
675 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
676 racoon_free(iph2
->spidx_gen
);
677 iph2
->spidx_gen
= NULL
;
681 oakley_dhgrp_free(iph2
->pfsgrp
);
685 VPTRINIT(iph2
->dhpriv
);
686 VPTRINIT(iph2
->dhpub
);
687 VPTRINIT(iph2
->dhpub_p
);
688 VPTRINIT(iph2
->dhgxy
);
690 VPTRINIT(iph2
->id_p
);
691 VPTRINIT(iph2
->nonce
);
692 VPTRINIT(iph2
->nonce_p
);
694 VPTRINIT(iph2
->sa_ret
);
697 oakley_delivm(iph2
->ivm
);
703 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
707 struct ph2handle
*iph2
;
712 racoon_free(iph2
->src
);
716 racoon_free(iph2
->dst
);
720 racoon_free(iph2
->src_id
);
724 racoon_free(iph2
->dst_id
);
728 if (iph2
->proposal
) {
729 flushsaprop(iph2
->proposal
);
730 iph2
->proposal
= NULL
;
733 if (iph2
->parent_session
) {
734 ike_session_unlink_ph2_from_session(iph2
);
737 unlink_sainfo_from_ph2(iph2
->sainfo
);
740 if (iph2
->ext_nat_id
) {
741 vfree(iph2
->ext_nat_id
);
742 iph2
->ext_nat_id
= NULL
;
744 if (iph2
->ext_nat_id_p
) {
745 vfree(iph2
->ext_nat_id_p
);
746 iph2
->ext_nat_id_p
= NULL
;
753 * create new isakmp Phase 2 status record to handle isakmp in Phase2
757 struct ph2handle
*iph2
;
759 LIST_INSERT_HEAD(&ph2tree
, iph2
, chain
);
766 struct ph2handle
*iph2
;
768 LIST_REMOVE(iph2
, chain
);
778 flushph2(int ignore_estab_or_assert_handles
)
780 struct ph2handle
*p
, *next
;
782 plog(LLV_DEBUG2
, LOCATION
, NULL
,
783 "flushing ph2 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles
);
785 for (p
= LIST_FIRST(&ph2tree
); p
; p
= next
) {
786 next
= LIST_NEXT(p
, chain
);
787 if (p
->is_dying
|| p
->status
== PHASE2ST_EXPIRED
) {
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");
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");
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
);
806 plog(LLV_DEBUG2
, LOCATION
, NULL
,
807 "got a ph2 handler to flush (state %d)\n", p
->status
);
810 ike_session_stopped_by_controller(p
->parent_session
,
811 ike_session_stopped_by_flush
);
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).
825 deleteallph2(src
, dst
, proto_id
)
826 struct sockaddr
*src
, *dst
;
829 struct ph2handle
*iph2
, *next
;
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
) {
837 if (iph2
->proposal
== NULL
&& iph2
->approval
== NULL
)
839 if (cmpsaddrwop(src
, iph2
->src
) != 0 ||
840 cmpsaddrwop(dst
, iph2
->dst
) != 0) {
843 if (iph2
->approval
!= NULL
) {
844 for (pr
= iph2
->approval
->head
; pr
!= NULL
;
846 if (proto_id
== pr
->proto_id
)
849 } else if (iph2
->proposal
!= NULL
) {
850 for (pr
= iph2
->proposal
->head
; pr
!= NULL
;
852 if (proto_id
== pr
->proto_id
)
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
);
871 * Delete all Phase 1 handlers for this src/dst.
874 deleteallph1(src
, dst
)
875 struct sockaddr
*src
, *dst
;
877 struct ph1handle
*iph1
, *next
;
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) {
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
);
890 ike_session_stopped_by_controller(iph1
->parent_session
,
891 ike_session_stopped_by_flush
);
900 struct ph1handle
*iph1
;
901 struct ph2handle
*iph2
;
903 if (iph2
->ph1
&& (struct ph1handle
*)iph2
->ph1bind
.le_next
== iph1
) {
904 plog(LLV_ERROR
, LOCATION
, NULL
, "duplicate %s.\n", __FUNCTION__
);
907 LIST_INSERT_HEAD(&iph1
->ph2tree
, iph2
, ph1bind
);
912 struct ph2handle
*iph2
;
914 if (iph2
->ph1
!= NULL
) {
915 plog(LLV_DEBUG
, LOCATION
, NULL
, "unbindph12.\n");
917 LIST_REMOVE(iph2
, ph1bind
);
922 rebindph12(new_ph1
, iph2
)
923 struct ph1handle
*new_ph1
;
924 struct ph2handle
*iph2
;
930 // reconcile the ph1-to-ph2 binding
931 plog(LLV_DEBUG
, LOCATION
, NULL
, "rebindph12.\n");
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");
946 /* %%% management contacted list */
948 * search contacted list.
952 struct sockaddr
*remote
;
956 LIST_FOREACH(p
, &ctdtree
, chain
) {
957 if (cmpsaddrstrict(remote
, p
->remote
) == 0)
965 * create new isakmp Phase 2 status record to handle isakmp in Phase2
969 struct sockaddr
*remote
;
971 struct contacted
*new;
973 /* create new iph2 */
974 new = racoon_calloc(1, sizeof(*new));
978 new->remote
= dupsaddr(remote
);
979 if (new->remote
== NULL
) {
980 plog(LLV_ERROR
, LOCATION
, NULL
,
981 "failed to allocate buffer.\n");
986 LIST_INSERT_HEAD(&ctdtree
, new, chain
);
995 struct contacted
*c
, *next
;
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
);
1008 LIST_INIT(&ctdtree
);
1012 get_exp_retx_interval (int num_retries
, int fixed_retry_interval
)
1014 // first 3 retries aren't exponential
1015 if (num_retries
<= 3) {
1016 return (time_t)fixed_retry_interval
;
1018 return (time_t)(num_retries
* fixed_retry_interval
);
1023 * check the response has been sent to the peer. when not, simply reply
1024 * the buffered packet to the peer.
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.
1032 check_recvdpkt(remote
, local
, rbuf
)
1033 struct sockaddr
*remote
, *local
;
1041 /* set current time */
1044 hash
= eay_md5_one(rbuf
);
1046 plog(LLV_ERROR
, LOCATION
, NULL
,
1047 "failed to allocate buffer.\n");
1051 LIST_FOREACH(r
, &rcptree
, chain
) {
1052 if (memcmp(hash
->v
, r
->hash
->v
, r
->hash
->l
) == 0)
1057 /* this is the first time to receive the packet */
1062 * the packet was processed before, but the remote address mismatches.
1063 * ignore the port to accomodate port changes (e.g. floating).
1065 if (cmpsaddrwop(remote
, r
->remote
) != 0) {
1070 * it should not check the local address because the packet
1071 * may arrive at other interface.
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",
1079 /*XXX should it be error ? */
1082 /* select the socket to be sent */
1083 s
= getsockmyaddr(r
->local
);
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
);
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
,
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
);
1110 /* resend the packet if needed */
1111 len
= sendfromto(s
, r
->sendbuf
->v
, r
->sendbuf
->l
,
1112 r
->local
, r
->remote
, lcconf
->count_persend
);
1115 plog(LLV_ERROR
, LOCATION
, NULL
, "sendfromto failed\n");
1119 /* check the retry counter */
1121 if (r
->retry_counter
<= 0) {
1124 plog(LLV_DEBUG
, LOCATION
, NULL
,
1125 "deleted the retransmission packet to %s.\n",
1129 r
->retry_interval
= get_exp_retx_interval((lcconf
->retry_counter
- r
->retry_counter
),
1130 lcconf
->retry_interval
);
1137 * adding a hash of received packet into the received list.
1140 add_recvdpkt(remote
, local
, sbuf
, rbuf
, non_esp
, frag_flags
)
1141 struct sockaddr
*remote
, *local
;
1142 vchar_t
*sbuf
, *rbuf
;
1144 u_int32_t frag_flags
;
1146 struct recvdpkt
*new = NULL
;
1148 if (lcconf
->retry_counter
== 0) {
1149 /* no need to add it */
1153 new = racoon_calloc(1, sizeof(*new));
1155 plog(LLV_ERROR
, LOCATION
, NULL
,
1156 "failed to allocate buffer.\n");
1160 new->hash
= eay_md5_one(rbuf
);
1162 plog(LLV_ERROR
, LOCATION
, NULL
,
1163 "failed to allocate buffer.\n");
1167 new->remote
= dupsaddr(remote
);
1168 if (new->remote
== NULL
) {
1169 plog(LLV_ERROR
, LOCATION
, NULL
,
1170 "failed to allocate buffer.\n");
1174 new->local
= dupsaddr(local
);
1175 if (new->local
== NULL
) {
1176 plog(LLV_ERROR
, LOCATION
, NULL
,
1177 "failed to allocate buffer.\n");
1183 plog (LLV_DEBUG
, LOCATION
, NULL
, "Adding NON-ESP marker\n");
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");
1194 *(u_int32_t
*)new->sendbuf
->v
= 0;
1195 memcpy(new->sendbuf
->v
+ non_esp
, sbuf
->v
, sbuf
->l
);
1197 new->sendbuf
= vdup(sbuf
);
1198 if (new->sendbuf
== NULL
) {
1199 plog(LLV_ERROR
, LOCATION
, NULL
,
1200 "failed to allocate buffer.\n");
1206 new->retry_counter
= lcconf
->retry_counter
;
1208 new->created
= time(NULL
);
1211 new->frag_flags
= frag_flags
;
1214 new->retry_interval
= get_exp_retx_interval((lcconf
->retry_counter
- new->retry_counter
),
1215 lcconf
->retry_interval
);
1217 LIST_INSERT_HEAD(&rcptree
, new, chain
);
1227 racoon_free(r
->remote
);
1229 racoon_free(r
->local
);
1241 LIST_REMOVE(r
, chain
);
1245 sweep_recvdpkt(dummy
)
1248 struct recvdpkt
*r
, *next
;
1251 /* set current time */
1254 /* set the lifetime of the retransmission */
1255 lt
= lcconf
->retry_counter
* lcconf
->retry_interval
;
1257 for (r
= LIST_FIRST(&rcptree
); r
; r
= next
) {
1258 next
= LIST_NEXT(r
, chain
);
1260 if (t
- r
->created
> lt
) {
1266 sched_new(lt
, sweep_recvdpkt
, &rcptree
);
1272 struct recvdpkt
*r
, *next
;
1274 for (r
= LIST_FIRST(&rcptree
); r
; r
= next
) {
1275 next
= LIST_NEXT(r
, chain
);
1279 sched_scrub_param(&rcptree
);
1285 time_t lt
= lcconf
->retry_counter
* lcconf
->retry_interval
;
1287 LIST_INIT(&rcptree
);
1289 sched_new(lt
, sweep_recvdpkt
, &rcptree
);
1292 #ifdef ENABLE_HYBRID
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
1298 exclude_cfg_addr(addr
)
1299 const struct sockaddr
*addr
;
1301 struct ph1handle
*p
;
1302 struct sockaddr_in
*sin
;
1304 LIST_FOREACH(p
, &ph1tree
, chain
) {
1305 if ((p
->mode_cfg
!= NULL
) &&
1306 (p
->mode_cfg
->flags
& ISAKMP_CFG_GOT_ADDR4
) &&
1307 (addr
->sa_family
== AF_INET
)) {
1308 sin
= (struct sockaddr_in
*)addr
;
1309 if (sin
->sin_addr
.s_addr
== p
->mode_cfg
->addr4
.s_addr
)
1318 #ifdef ENABLE_HYBRID
1320 getph1bylogin(login
)
1323 struct ph1handle
*p
;
1325 LIST_FOREACH(p
, &ph1tree
, chain
) {
1326 if (p
->mode_cfg
== NULL
)
1328 if (strncmp(p
->mode_cfg
->login
, login
, LOGINLEN
) == 0)
1336 purgeph1bylogin(login
)
1339 struct ph1handle
*p
;
1342 LIST_FOREACH(p
, &ph1tree
, chain
) {
1343 if (p
->mode_cfg
== NULL
)
1345 if (strncmp(p
->mode_cfg
->login
, login
, LOGINLEN
) == 0) {
1346 if (p
->status
== PHASE1ST_ESTABLISHED
)
1347 isakmp_info_send_d1(p
);
1357 purgephXbydstaddrwop(remote
)
1358 struct sockaddr
*remote
;
1361 struct ph1handle
*p
;
1362 struct ph2handle
*p2
;
1364 LIST_FOREACH(p2
, &ph2tree
, chain
) {
1365 if (cmpsaddrwop(remote
, p2
->dst
) == 0) {
1366 plog(LLV_WARNING
, LOCATION
, NULL
,
1367 "in %s... purging phase2s\n", __FUNCTION__
);
1368 if (p2
->status
== PHASE2ST_ESTABLISHED
)
1369 isakmp_info_send_d2(p2
);
1370 if (p2
->status
< PHASE2ST_EXPIRED
) {
1371 isakmp_ph2expire(p2
);
1373 isakmp_ph2delete(p2
);
1379 LIST_FOREACH(p
, &ph1tree
, chain
) {
1380 if (cmpsaddrwop(remote
, p
->remote
) == 0) {
1381 plog(LLV_WARNING
, LOCATION
, NULL
,
1382 "in %s... purging phase1 and related phase2s\n", __FUNCTION__
);
1383 ike_session_purge_ph2s_by_ph1(p
);
1384 if (p
->status
== PHASE1ST_ESTABLISHED
)
1385 isakmp_info_send_d1(p
);
1386 isakmp_ph1expire(p
);
1395 purgephXbyspid(u_int32_t spid
,
1398 struct ph2handle
*iph2
;
1399 struct ph1handle
*iph1
;
1401 // do ph2's first... we need the ph1s for notifications
1402 LIST_FOREACH(iph2
, &ph2tree
, chain
) {
1403 if (spid
== iph2
->spid
) {
1404 if (iph2
->is_dying
|| iph2
->status
== PHASE2ST_EXPIRED
) {
1407 if (iph2
->status
== PHASE2ST_ESTABLISHED
) {
1408 isakmp_info_send_d2(iph2
);
1410 ike_session_stopped_by_controller(iph2
->parent_session
,
1411 ike_session_stopped_by_flush
);
1412 isakmp_ph2expire(iph2
); // iph2 will go down 1 second later.
1416 // do the ph1s last.
1417 LIST_FOREACH(iph2
, &ph2tree
, chain
) {
1418 if (spid
== iph2
->spid
) {
1419 if (del_boundph1
&& iph2
->parent_session
) {
1420 for (iph1
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph1tree
); iph1
; iph1
= LIST_NEXT(iph1
, ph1ofsession_chain
)) {
1421 if (iph1
->is_dying
|| iph1
->status
== PHASE1ST_EXPIRED
) {
1424 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
1425 isakmp_info_send_d1(iph1
);
1427 isakmp_ph1expire(iph1
);
1438 ph1_force_dpd (struct sockaddr
*remote
)
1441 struct ph1handle
*p
;
1443 LIST_FOREACH(p
, &ph1tree
, chain
) {
1444 if (cmpsaddrwop(remote
, p
->remote
) == 0) {
1445 if (p
->status
== PHASE1ST_ESTABLISHED
&&
1448 p
->rmconf
->dpd_interval
) {
1450 isakmp_info_send_r_u(p
);
1453 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping forced-DPD for phase1 (dpd already in progress).\n");
1455 if (p
->parent_session
) {
1456 p
->parent_session
->controller_awaiting_peer_resp
= 1;
1459 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping forced-DPD for phase1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
1460 p
->status
, p
->is_dying
, p
->dpd_support
, p
->rmconf
->dpd_interval
);
1470 sweep_sleepwake(void)
1472 struct ph2handle
*iph2
;
1473 struct ph1handle
*iph1
;
1476 LIST_FOREACH(iph1
, &ph1tree
, chain
) {
1477 if (iph1
->parent_session
&& iph1
->parent_session
->is_asserted
) {
1478 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of phase1 %s because it's been asserted.\n",
1479 isakmp_pindex(&iph1
->index
, 0));
1482 if (iph1
->is_dying
|| iph1
->status
>= PHASE1ST_EXPIRED
) {
1483 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of phase1 %s because it's already expired.\n",
1484 isakmp_pindex(&iph1
->index
, 0));
1488 if (iph1
->sce
->xtime
<= swept_at
) {
1489 SCHED_KILL(iph1
->sce
);
1490 SCHED_KILL(iph1
->sce_rekey
);
1492 iph1
->status
= PHASE1ST_EXPIRED
;
1493 ike_session_update_ph1_ph2tree(iph1
); // move unbind/rebind ph2s to from current ph1
1494 iph1
->sce
= sched_new(1, isakmp_ph1delete_stub
, iph1
);
1495 plog(LLV_DEBUG2
, LOCATION
, NULL
, "phase1 %s expired while sleeping: quick deletion.\n",
1496 isakmp_pindex(&iph1
->index
, 0));
1499 if (iph1
->sce_rekey
) {
1500 if (iph1
->status
== PHASE1ST_EXPIRED
|| iph1
->sce_rekey
->xtime
<= swept_at
) {
1501 SCHED_KILL(iph1
->sce_rekey
);
1505 if (iph1
->status
== PHASE1ST_EXPIRED
|| iph1
->scr
->xtime
<= swept_at
) {
1506 SCHED_KILL(iph1
->scr
);
1510 if (iph1
->dpd_r_u
) {
1511 if (iph1
->status
== PHASE1ST_EXPIRED
|| iph1
->dpd_r_u
->xtime
<= swept_at
) {
1512 SCHED_KILL(iph1
->dpd_r_u
);
1519 LIST_FOREACH(iph2
, &ph2tree
, chain
) {
1520 if (iph2
->parent_session
&& iph2
->parent_session
->is_asserted
) {
1521 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of phase2 because it's been asserted.\n");
1524 if (iph2
->is_dying
|| iph2
->status
>= PHASE2ST_EXPIRED
) {
1525 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of phase2 because it's already expired.\n");
1529 if (iph2
->sce
->xtime
<= swept_at
) {
1530 iph2
->status
= PHASE2ST_EXPIRED
;
1532 isakmp_ph2expire(iph2
); // iph2 will go down 1 second later.
1533 ike_session_stopped_by_controller(iph2
->parent_session
,
1534 ike_session_stopped_by_sleepwake
);
1535 plog(LLV_DEBUG2
, LOCATION
, NULL
, "phase2 expired while sleeping: quick deletion.\n");
1539 if (iph2
->status
== PHASE2ST_EXPIRED
|| iph2
->scr
->xtime
<= swept_at
) {
1540 SCHED_KILL(iph2
->scr
);
1545 // do the ike_session last
1546 ike_session_sweep_sleepwake();