2 * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/param.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
36 #include "isakmp_var.h"
38 #include "ike_session.h"
41 #include "nattraversal.h"
44 #include "ipsec_doi.h"
45 #include "ipsecSessionTracer.h"
46 #include "ipsecMessageTracer.h"
47 #include "isakmp_inf.h"
48 #include "localconf.h"
49 #include "remoteconf.h"
50 #include "vpn_control.h"
51 #include "vpn_control_var.h"
54 #include "power_mgmt.h"
56 #define GET_SAMPLE_PERIOD(s,m) do { \
66 const char *ike_session_stopped_by_vpn_disconnect
= "Stopped by VPN disconnect";
67 const char *ike_session_stopped_by_controller_comm_lost
= "Stopped by loss of controller communication";
68 const char *ike_session_stopped_by_flush
= "Stopped by Flush";
69 const char *ike_session_stopped_by_idle
= "Stopped by Idle";
70 const char *ike_session_stopped_by_xauth_timeout
= "Stopped by XAUTH timeout";
71 const char *ike_session_stopped_by_sleepwake
= "Stopped by Sleep-Wake";
72 const char *ike_session_stopped_by_assert
= "Stopped by Assert";
73 const char *ike_session_stopped_by_peer
= "Stopped by Peer";
75 LIST_HEAD(_ike_session_tree_
, ike_session
) ike_session_tree
= { NULL
};
77 static void ike_session_bindph12(phase1_handle_t
*, phase2_handle_t
*);
78 static void ike_session_rebindph12(phase1_handle_t
*, phase2_handle_t
*);
79 static void ike_session_unbind_all_ph2_from_ph1 (phase1_handle_t
*);
80 static void ike_session_rebind_all_ph12_to_new_ph1 (phase1_handle_t
*, phase1_handle_t
*);
82 static ike_session_t
*
83 new_ike_session (ike_session_id_t
*id
)
85 ike_session_t
*session
;
88 plog(ASL_LEVEL_DEBUG
, "Invalid parameters in %s.\n", __FUNCTION__
);
92 session
= racoon_calloc(1, sizeof(*session
));
94 bzero(session
, sizeof(*session
));
95 memcpy(&session
->session_id
, id
, sizeof(*id
));
96 LIST_INIT(&session
->ph1tree
);
97 LIST_INIT(&session
->ph2tree
);
98 LIST_INSERT_HEAD(&ike_session_tree
, session
, chain
);
99 IPSECSESSIONTRACERSTART(session
);
105 free_ike_session (ike_session_t
*session
)
107 int is_failure
= TRUE
;
109 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
110 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
111 SCHED_KILL(session
->sc_xauth
);
112 if (session
->start_timestamp
.tv_sec
|| session
->start_timestamp
.tv_usec
) {
113 if (!(session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
)) {
114 gettimeofday(&session
->stop_timestamp
, NULL
);
116 if (session
->term_reason
!= ike_session_stopped_by_vpn_disconnect
||
117 session
->term_reason
!= ike_session_stopped_by_controller_comm_lost
||
118 session
->term_reason
!= ike_session_stopped_by_flush
||
119 session
->term_reason
!= ike_session_stopped_by_idle
) {
122 IPSECSESSIONTRACERSTOP(session
,
124 session
->term_reason
);
126 // do MessageTracer cleanup here
127 plog(ASL_LEVEL_DEBUG
,
128 "Freeing IKE-Session to %s.\n",
129 saddr2str((struct sockaddr
*)&session
->session_id
.remote
));
130 LIST_REMOVE(session
, chain
);
131 racoon_free(session
);
137 ike_session_init (void)
139 LIST_INIT(&ike_session_tree
);
143 ike_session_get_rekey_lifetime (int local_spi_is_higher
, u_int expiry_lifetime
)
145 u_int rekey_lifetime
= expiry_lifetime
/ 10;
147 if (rekey_lifetime
) {
148 if (local_spi_is_higher
) {
149 return (rekey_lifetime
* 9);
151 return (rekey_lifetime
* 8);
154 if (local_spi_is_higher
) {
155 rekey_lifetime
= expiry_lifetime
- 1;
157 rekey_lifetime
= expiry_lifetime
- 2;
160 if (rekey_lifetime
< expiry_lifetime
) {
161 return rekey_lifetime
;
167 ike_session_create_session (ike_session_id_t
*session_id
)
172 plog(ASL_LEVEL_DEBUG
, "New IKE Session to %s.\n", saddr2str((struct sockaddr
*)&session_id
->remote
));
174 return new_ike_session(session_id
);
178 ike_session_release_session (ike_session_t
*session
)
180 while (!LIST_EMPTY(&session
->ph2tree
)) {
181 phase2_handle_t
*phase2
= LIST_FIRST(&session
->ph2tree
);
182 ike_session_unlink_phase2(phase2
);
185 while (!LIST_EMPTY(&session
->ph1tree
)) {
186 phase1_handle_t
*phase1
= LIST_FIRST(&session
->ph1tree
);
187 ike_session_unlink_phase1(phase1
);
191 // %%%%%%%%% re-examine this - keep both floated and unfloated port when behind nat
193 ike_session_get_session (struct sockaddr_storage
*local
,
194 struct sockaddr_storage
*remote
,
197 ike_session_t
*p
= NULL
;
199 ike_session_id_t id_default
;
200 ike_session_id_t id_floated_default
;
201 ike_session_id_t id_wop
;
202 ike_session_t
*best_match
= NULL
;
203 u_int16_t remote_port
;
204 int is_isakmp_remote_port
;
206 if (!local
|| !remote
) {
207 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
211 remote_port
= extract_port(remote
);
212 if (remote_port
&& remote_port
!= PORT_ISAKMP
&& remote_port
!= PORT_ISAKMP_NATT
) {
213 is_isakmp_remote_port
= 0;
215 is_isakmp_remote_port
= 1;
218 /* we will try a couple of matches first: if the exact id isn't found, then we'll try for an id that has zero'd ports */
219 bzero(&id
, sizeof(id
));
220 bzero(&id_default
, sizeof(id_default
));
221 bzero(&id_floated_default
, sizeof(id_floated_default
));
222 bzero(&id_wop
, sizeof(id_wop
));
223 if (local
->ss_family
== AF_INET
) {
224 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in
));
225 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in
));
226 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in
));
227 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in
));
228 } else if (local
->ss_family
== AF_INET6
) {
229 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in6
));
230 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in6
));
231 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in6
));
232 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in6
));
234 set_port(&id_default
.local
, PORT_ISAKMP
);
235 set_port(&id_floated_default
.local
, PORT_ISAKMP_NATT
);
236 set_port(&id_wop
.local
, 0);
237 if (remote
->ss_family
== AF_INET
) {
238 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in
));
239 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in
));
240 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in
));
241 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in
));
242 } else if (remote
->ss_family
== AF_INET6
) {
243 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in6
));
244 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
245 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
246 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in6
));
248 set_port(&id_default
.remote
, PORT_ISAKMP
);
249 set_port(&id_floated_default
.remote
, PORT_ISAKMP_NATT
);
250 set_port(&id_wop
.remote
, 0);
252 plog(ASL_LEVEL_DEBUG
,
253 "start search for IKE-Session. target %s.\n",
254 saddr2str((struct sockaddr
*)remote
));
256 LIST_FOREACH(p
, &ike_session_tree
, chain
) {
257 plog(ASL_LEVEL_DEBUG
,
258 "still search for IKE-Session. this %s.\n",
259 saddr2str((struct sockaddr
*)&p
->session_id
.remote
));
261 // for now: ignore any stopped sessions as they will go down
262 if (p
->is_dying
|| p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
263 plog(ASL_LEVEL_DEBUG
, "still searching. skipping... session to %s is already stopped, active ph1 %d ph2 %d.\n",
264 saddr2str((struct sockaddr
*)&p
->session_id
.remote
),
265 p
->ikev1_state
.active_ph1cnt
, p
->ikev1_state
.active_ph2cnt
);
269 if (memcmp(&p
->session_id
, &id
, sizeof(id
)) == 0) {
270 plog(ASL_LEVEL_DEBUG
,
271 "Pre-existing IKE-Session to %s. case 1.\n",
272 saddr2str((struct sockaddr
*)remote
));
274 } else if (is_isakmp_remote_port
&& memcmp(&p
->session_id
, &id_default
, sizeof(id_default
)) == 0) {
275 plog(ASL_LEVEL_DEBUG
,
276 "Pre-existing IKE-Session to %s. case 2.\n",
277 saddr2str((struct sockaddr
*)remote
));
279 } else if (is_isakmp_remote_port
&& p
->ports_floated
&& memcmp(&p
->session_id
, &id_floated_default
, sizeof(id_floated_default
)) == 0) {
280 plog(ASL_LEVEL_DEBUG
,
281 "Pre-existing IKE-Session to %s. case 3.\n",
282 saddr2str((struct sockaddr
*)remote
));
284 } else if (is_isakmp_remote_port
&& memcmp(&p
->session_id
, &id_wop
, sizeof(id_wop
)) == 0) {
289 plog(ASL_LEVEL_DEBUG
,
290 "Best-match IKE-Session to %s.\n",
291 saddr2str((struct sockaddr
*)&best_match
->session_id
.remote
));
294 if (alloc_if_absent
) {
295 plog(ASL_LEVEL_DEBUG
,
296 "New IKE-Session to %s.\n",
297 saddr2str((struct sockaddr
*)&id
.remote
));
298 return new_ike_session(&id
);
305 ike_session_init_traffic_cop_params (phase1_handle_t
*iph1
)
309 (!iph1
->rmconf
->idle_timeout
&& !iph1
->rmconf
->dpd_interval
)) {
313 if (!iph1
->parent_session
->traffic_monitor
.interv_idle
) {
314 iph1
->parent_session
->traffic_monitor
.interv_idle
= iph1
->rmconf
->idle_timeout
;
316 if (!iph1
->parent_session
->traffic_monitor
.dir_idle
) {
317 iph1
->parent_session
->traffic_monitor
.dir_idle
= iph1
->rmconf
->idle_timeout_dir
;
320 if (!iph1
->parent_session
->traffic_monitor
.interv_mon
) {
321 int min_period
, max_period
, sample_period
= 0;
323 /* calculate the sampling interval... half the smaller interval */
324 if (iph1
->rmconf
->dpd_interval
&&
325 (iph1
->rmconf
->dpd_algo
== DPD_ALGO_INBOUND_DETECT
||
326 iph1
->rmconf
->dpd_algo
== DPD_ALGO_BLACKHOLE_DETECT
)) {
327 // when certain types of dpd are enabled
328 min_period
= MIN(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
329 max_period
= MAX(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
330 } else if (iph1
->rmconf
->idle_timeout
) {
331 min_period
= max_period
= iph1
->rmconf
->idle_timeout
;
333 // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic
337 GET_SAMPLE_PERIOD(sample_period
, min_period
);
339 GET_SAMPLE_PERIOD(sample_period
, max_period
);
341 iph1
->parent_session
->traffic_monitor
.interv_mon
= sample_period
;
346 ike_session_update_mode (phase2_handle_t
*iph2
)
348 if (!iph2
|| !iph2
->parent_session
) {
351 if (iph2
->phase2_type
!= PHASE2_TYPE_SA
)
353 if (iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV2
) {
356 // exit early if we already detected cisco-ipsec
357 if (iph2
->parent_session
->is_cisco_ipsec
) {
361 if (iph2
->approval
) {
362 if (!ipsecdoi_any_transportmode(iph2
->approval
)) {
363 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
364 iph2
->parent_session
->is_cisco_ipsec
= 0;
365 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
366 iph2
->parent_session
->is_btmm_ipsec
= 1;
368 } else if (ipsecdoi_transportmode(iph2
->approval
)) {
369 iph2
->parent_session
->is_cisco_ipsec
= 0;
370 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
371 iph2
->parent_session
->is_btmm_ipsec
= 0;
374 } else if (iph2
->proposal
) {
375 if (!ipsecdoi_any_transportmode(iph2
->proposal
)) {
376 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
377 iph2
->parent_session
->is_cisco_ipsec
= 0;
378 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
379 iph2
->parent_session
->is_btmm_ipsec
= 1;
381 } else if (ipsecdoi_transportmode(iph2
->proposal
)) {
382 iph2
->parent_session
->is_cisco_ipsec
= 0;
383 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
384 iph2
->parent_session
->is_btmm_ipsec
= 0;
391 ike_session_cleanup_xauth_timeout (void *arg
)
393 ike_session_t
*session
= (ike_session_t
*)arg
;
395 SCHED_KILL(session
->sc_xauth
);
396 // if there are no more established ph2s, start a timer to teardown the session
397 if (!ike_session_has_established_ph2(session
)) {
398 ike_session_cleanup(session
, ike_session_stopped_by_xauth_timeout
);
400 session
->sc_xauth
= sched_new(300 /* 5 mins */,
401 ike_session_cleanup_xauth_timeout
,
407 ike_session_link_phase1 (ike_session_t
*session
, phase1_handle_t
*iph1
)
410 if (!session
|| !iph1
) {
411 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
415 gettimeofday(&session
->start_timestamp
, NULL
);
417 if (iph1
->started_by_api
) {
418 session
->is_cisco_ipsec
= 1;
419 session
->is_l2tpvpn_ipsec
= 0;
420 session
->is_btmm_ipsec
= 0;
422 iph1
->parent_session
= session
;
423 LIST_INSERT_HEAD(&session
->ph1tree
, iph1
, ph1ofsession_chain
);
424 session
->ikev1_state
.active_ph1cnt
++;
425 if ((!session
->ikev1_state
.ph1cnt
&&
426 iph1
->side
== INITIATOR
) ||
427 iph1
->started_by_api
) {
428 // client initiates the first phase1 or, is started by controller api
429 session
->is_client
= 1;
431 if (session
->established
&&
432 session
->ikev1_state
.ph1cnt
&&
433 iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
436 session
->ikev1_state
.ph1cnt
++;
437 ike_session_init_traffic_cop_params(iph1
);
443 ike_session_link_phase2 (ike_session_t
*session
, phase2_handle_t
*iph2
)
446 plog(ASL_LEVEL_DEBUG
, "Invalid parameters in %s.\n", __FUNCTION__
);
449 if (iph2
->parent_session
) {
450 plog(ASL_LEVEL_ERR
, "Phase 2 already linked to session %s.\n", __FUNCTION__
);
453 iph2
->parent_session
= session
;
454 LIST_INSERT_HEAD(&session
->ph2tree
, iph2
, ph2ofsession_chain
);
455 session
->ikev1_state
.active_ph2cnt
++;
456 if (!session
->ikev1_state
.ph2cnt
&&
457 iph2
->side
== INITIATOR
) {
458 // client initiates the first phase2
459 session
->is_client
= 1;
461 if (iph2
->phase2_type
== PHASE2_TYPE_SA
&&
462 session
->established
&&
463 session
->ikev1_state
.ph2cnt
&&
464 iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
467 session
->ikev1_state
.ph2cnt
++;
468 ike_session_update_mode(iph2
);
474 ike_session_link_ph2_to_ph1 (phase1_handle_t
*iph1
, phase2_handle_t
*iph2
)
476 struct sockaddr_storage
*local
;
477 struct sockaddr_storage
*remote
;
481 plog(ASL_LEVEL_DEBUG
, "Invalid parameters in %s.\n", __FUNCTION__
);
485 plog(ASL_LEVEL_ERR
, "Phase 2 already linked %s.\n", __FUNCTION__
);
486 if (iph2
->ph1
== iph1
)
489 return -1; // This shouldn't happen
495 if (iph2
->parent_session
== NULL
)
496 if ((error
= ike_session_link_phase2(iph1
->parent_session
, iph2
)))
499 ike_session_bindph12(iph1
, iph2
);
504 ike_session_unlink_phase1 (phase1_handle_t
*iph1
)
506 ike_session_t
*session
;
508 if (!iph1
|| !iph1
->parent_session
) {
509 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
513 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
514 if (LIST_FIRST(&iph1
->bound_ph2tree
)) {
515 // reparent any phase2 that may be hanging on to this phase1
516 ike_session_update_ph1_ph2tree(iph1
);
520 sched_scrub_param(iph1
);
521 session
= iph1
->parent_session
;
522 LIST_REMOVE(iph1
, ph1ofsession_chain
);
523 iph1
->parent_session
= NULL
;
524 session
->ikev1_state
.active_ph1cnt
--;
525 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
526 session
->is_dying
= 1;
527 free_ike_session(session
);
529 ike_session_delph1(iph1
);
534 ike_session_unlink_phase2 (phase2_handle_t
*iph2
)
536 ike_session_t
*session
;
538 if (!iph2
|| !iph2
->parent_session
) {
539 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
542 sched_scrub_param(iph2
);
543 ike_session_unbindph12(iph2
);
545 LIST_REMOVE(iph2
, ph2ofsession_chain
);
546 session
= iph2
->parent_session
;
547 iph2
->parent_session
= NULL
;
548 session
->ikev1_state
.active_ph2cnt
--;
549 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
550 session
->is_dying
= 1;
551 free_ike_session(session
);
553 ike_session_delph2(iph2
);
559 ike_session_update_ph1_ph2tree (phase1_handle_t
*iph1
)
561 phase1_handle_t
*new_iph1
= NULL
;
564 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
568 if (iph1
->parent_session
) {
569 new_iph1
= ike_session_get_established_ph1(iph1
->parent_session
);
572 plog(ASL_LEVEL_DEBUG
, "no ph1bind replacement found. NULL ph1.\n");
573 ike_session_unbind_all_ph2_from_ph1(iph1
);
574 } else if (iph1
== new_iph1
) {
575 plog(ASL_LEVEL_DEBUG
, "no ph1bind replacement found. same ph1.\n");
576 ike_session_unbind_all_ph2_from_ph1(iph1
);
578 ike_session_rebind_all_ph12_to_new_ph1(iph1
, new_iph1
);
581 plog(ASL_LEVEL_DEBUG
, "invalid parent session in %s.\n", __FUNCTION__
);
587 ike_session_update_ph2_ph1bind (phase2_handle_t
*iph2
)
589 phase1_handle_t
*iph1
;
591 if (!iph2
|| iph2
->phase2_type
!= PHASE2_TYPE_SA
) {
592 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
596 iph1
= ike_session_get_established_ph1(iph2
->parent_session
);
597 if (iph1
&& iph2
->ph1
&& iph1
!= iph2
->ph1
) {
598 ike_session_rebindph12(iph1
, iph2
);
599 } else if (iph1
&& !iph2
->ph1
) {
600 ike_session_bindph12(iph1
, iph2
);
607 ike_session_get_established_or_negoing_ph1 (ike_session_t
*session
)
609 phase1_handle_t
*p
, *iph1
= NULL
;
612 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
616 // look for the most mature ph1 under the session
617 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
618 if (!p
->is_dying
&& (FSM_STATE_IS_ESTABLISHED(p
->status
) || FSM_STATE_IS_NEGOTIATING(p
->status
))) {
619 if (!iph1
|| p
->status
> iph1
->status
) {
621 } else if (iph1
&& p
->status
== iph1
->status
) {
622 // TODO: pick better one based on farthest rekey/expiry remaining
631 ike_session_get_established_ph1 (ike_session_t
*session
)
636 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
640 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
641 if (!p
->is_dying
&& FSM_STATE_IS_ESTABLISHED(p
->status
)) {
651 ike_session_has_other_established_ph1 (ike_session_t
*session
, phase1_handle_t
*iph1
)
659 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
660 if (iph1
!= p
&& !p
->is_dying
) {
661 if (FSM_STATE_IS_ESTABLISHED(p
->status
) && p
->sce_rekey
) {
671 ike_session_has_other_negoing_ph1 (ike_session_t
*session
, phase1_handle_t
*iph1
)
676 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
680 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
681 if (iph1
!= p
&& !p
->is_dying
) {
682 if (FSM_STATE_IS_NEGOTIATING(p
->status
)) {
692 ike_session_has_other_established_ph2 (ike_session_t
*session
, phase2_handle_t
*iph2
)
697 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
701 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
702 if (p
->phase2_type
== PHASE2_TYPE_SA
&& iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
703 if (FSM_STATE_IS_ESTABLISHED(p
->status
)) {
713 ike_session_has_other_negoing_ph2 (ike_session_t
*session
, phase2_handle_t
*iph2
)
718 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
722 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
723 plog(ASL_LEVEL_DEBUG
, "%s: ph2 sub spid %d, db spid %d\n", __FUNCTION__
, iph2
->spid
, p
->spid
);
724 if (p
->phase2_type
== PHASE2_TYPE_SA
&& iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
725 if (FSM_STATE_IS_NEGOTIATING(p
->status
)) {
736 ike_session_ikev1_float_ports (phase1_handle_t
*iph1
)
738 struct sockaddr_storage
*local
, *remote
;
741 if (iph1
->parent_session
) {
742 local
= &iph1
->parent_session
->session_id
.local
;
743 remote
= &iph1
->parent_session
->session_id
.remote
;
745 set_port(local
, extract_port(iph1
->local
));
746 set_port(remote
, extract_port(iph1
->remote
));
747 iph1
->parent_session
->ports_floated
= 1;
749 LIST_FOREACH(p
, &iph1
->parent_session
->ph2tree
, ph2ofsession_chain
) {
754 set_port(local
, extract_port(iph1
->local
));
755 set_port(remote
, extract_port(iph1
->remote
));
758 plog(ASL_LEVEL_DEBUG
, "invalid parent session in %s.\n", __FUNCTION__
);
763 ike_session_traffic_cop (void *arg
)
765 ike_session_t
*session
= (__typeof__(session
))arg
;
768 (session
->established
&& !session
->stopped_by_vpn_controller
&& !session
->stop_timestamp
.tv_sec
&& !session
->stop_timestamp
.tv_usec
)) {
769 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
770 /* get traffic query from kernel */
771 if (pk_sendget_inbound_sastats(session
) < 0) {
773 plog(ASL_LEVEL_DEBUG
, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__
);
775 if (pk_sendget_outbound_sastats(session
) < 0) {
777 plog(ASL_LEVEL_DEBUG
, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__
);
779 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
780 ike_session_traffic_cop
,
784 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
789 ike_session_cleanup_idle (void *arg
)
791 ike_session_cleanup((ike_session_t
*)arg
, ike_session_stopped_by_idle
);
795 ike_session_monitor_idle (ike_session_t
*session
)
800 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_INBOUND
||
801 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
802 if (session
->peer_sent_data_sc_idle
) {
803 plog(ASL_LEVEL_DEBUG
, "%s: restart idle-timeout because peer sent data. monitoring dir %d.\n",
804 __FUNCTION__
, session
->traffic_monitor
.dir_idle
);
805 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
806 if (session
->traffic_monitor
.interv_idle
) {
807 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
808 ike_session_cleanup_idle
,
811 session
->peer_sent_data_sc_idle
= 0;
812 session
->i_sent_data_sc_idle
= 0;
816 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_OUTBOUND
||
817 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
818 if (session
->i_sent_data_sc_idle
) {
819 plog(ASL_LEVEL_DEBUG
, "%s: restart idle-timeout because i sent data. monitoring dir %d.\n",
820 __FUNCTION__
, session
->traffic_monitor
.dir_idle
);
821 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
822 if (session
->traffic_monitor
.interv_idle
) {
823 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
824 ike_session_cleanup_idle
,
827 session
->peer_sent_data_sc_idle
= 0;
828 session
->i_sent_data_sc_idle
= 0;
835 ike_session_start_traffic_mon (ike_session_t
*session
)
837 if (session
->traffic_monitor
.interv_mon
) {
838 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
839 ike_session_traffic_cop
,
842 if (session
->traffic_monitor
.interv_idle
) {
843 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
844 ike_session_cleanup_idle
,
850 ike_session_ph2_established (phase2_handle_t
*iph2
)
852 if (!iph2
->parent_session
|| iph2
->phase2_type
!= PHASE2_TYPE_SA
) {
853 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
856 SCHED_KILL(iph2
->parent_session
->sc_xauth
);
857 if (!iph2
->parent_session
->established
) {
858 gettimeofday(&iph2
->parent_session
->estab_timestamp
, NULL
);
859 iph2
->parent_session
->established
= 1;
860 IPSECSESSIONTRACERESTABLISHED(iph2
->parent_session
);
861 ike_session_start_traffic_mon(iph2
->parent_session
);
862 } else if (iph2
->parent_session
->is_asserted
) {
863 ike_session_start_traffic_mon(iph2
->parent_session
);
865 iph2
->parent_session
->is_asserted
= 0;
866 // nothing happening to this session
867 iph2
->parent_session
->term_reason
= NULL
;
869 ike_session_update_mode(iph2
);
870 if (iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV1
)
871 ike_session_unbindph12(iph2
);
873 #ifdef ENABLE_VPNCONTROL_PORT
874 vpncontrol_notify_peer_resp_ph2(1, iph2
);
875 #endif /* ENABLE_VPNCONTROL_PORT */
876 plog(ASL_LEVEL_DEBUG
, "%s: ph2 established, spid %d\n", __FUNCTION__
, iph2
->spid
);
880 ike_session_cleanup_ph1 (phase1_handle_t
*iph1
)
882 if (FSM_STATE_IS_EXPIRED(iph1
->status
)) {
883 // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL
884 iph1
->sce
= sched_new(1, isakmp_ph1delete_stub
, iph1
);
888 /* send delete information */
889 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
)) {
890 isakmp_info_send_d1(iph1
);
893 isakmp_ph1expire(iph1
);
897 ike_session_cleanup_ph1_stub (void *p
)
900 ike_session_cleanup_ph1((phase1_handle_t
*)p
);
904 ike_session_replace_other_ph1 (phase1_handle_t
*new_iph1
,
905 phase1_handle_t
*old_iph1
)
907 char *local
, *remote
, *index
;
908 ike_session_t
*session
= NULL
;
911 session
= new_iph1
->parent_session
;
913 if (!session
|| !new_iph1
|| !old_iph1
|| session
!= old_iph1
->parent_session
|| new_iph1
== old_iph1
) {
914 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
919 * if we are responder, then we should wait until the server sends a delete notification.
921 if ((new_iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV2
|| session
->is_client
) &&
922 new_iph1
->side
== RESPONDER
) {
926 SCHED_KILL(old_iph1
->sce
);
927 SCHED_KILL(old_iph1
->sce_rekey
);
928 old_iph1
->is_dying
= 1;
931 local
= racoon_strdup(saddr2str((struct sockaddr
*)old_iph1
->local
));
932 remote
= racoon_strdup(saddr2str((struct sockaddr
*)old_iph1
->remote
));
933 index
= racoon_strdup(isakmp_pindex(&old_iph1
->index
, 0));
935 STRDUP_FATAL(remote
);
937 plog(ASL_LEVEL_DEBUG
, "ISAKMP-SA %s-%s (spi:%s) needs to be deleted, replaced by (spi:%s)\n", local
, remote
, index
, isakmp_pindex(&new_iph1
->index
, 0));
942 // first rebind the children ph2s of this dying ph1 to the new ph1.
943 ike_session_rebind_all_ph12_to_new_ph1 (old_iph1
, new_iph1
);
945 if (old_iph1
->side
== INITIATOR
) {
946 /* everyone deletes old outbound SA */
947 old_iph1
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, old_iph1
);
949 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
950 old_iph1
->sce
= sched_new(7, ike_session_cleanup_ph1_stub
, old_iph1
);
955 ike_session_cleanup_other_established_ph1s (ike_session_t
*session
,
956 phase1_handle_t
*new_iph1
)
958 phase1_handle_t
*p
, *next
;
959 char *local
, *remote
;
961 if (!session
|| !new_iph1
|| session
!= new_iph1
->parent_session
) {
962 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
967 * if we are responder, then we should wait until the server sends a delete notification.
969 if ((new_iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV2
|| session
->is_client
) &&
970 new_iph1
->side
== RESPONDER
) {
974 LIST_FOREACH_SAFE(p
, &session
->ph1tree
, ph1ofsession_chain
, next
) {
976 * TODO: currently, most recently established SA wins. Need to revisit to see if
977 * alternative selections is better (e.g. largest p->index stays).
979 if (p
!= new_iph1
&& !p
->is_dying
) {
981 SCHED_KILL(p
->sce_rekey
);
985 local
= racoon_strdup(saddr2str((struct sockaddr
*)p
->local
));
986 remote
= racoon_strdup(saddr2str((struct sockaddr
*)p
->remote
));
988 STRDUP_FATAL(remote
);
989 plog(ASL_LEVEL_DEBUG
,
990 "ISAKMP-SA needs to be deleted %s-%s spi:%s\n",
991 local
, remote
, isakmp_pindex(&p
->index
, 0));
995 // first rebind the children ph2s of this dying ph1 to the new ph1.
996 ike_session_rebind_all_ph12_to_new_ph1 (p
, new_iph1
);
998 if (p
->side
== INITIATOR
) {
999 /* everyone deletes old outbound SA */
1000 p
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, p
);
1002 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
1003 p
->sce
= sched_new(7, ike_session_cleanup_ph1_stub
, p
);
1010 ike_session_cleanup_ph2 (phase2_handle_t
*iph2
)
1012 if (iph2
->phase2_type
!= PHASE2_TYPE_SA
)
1014 if (FSM_STATE_IS_EXPIRED(iph2
->status
)) {
1018 SCHED_KILL(iph2
->sce
);
1021 "about to cleanup ph2: status %d, seq %d dying %d\n",
1022 iph2
->status
, iph2
->seq
, iph2
->is_dying
);
1024 /* send delete information */
1025 if (FSM_STATE_IS_ESTABLISHED(iph2
->status
)) {
1026 isakmp_info_send_d2(iph2
);
1028 // delete outgoing SAs
1029 if (iph2
->approval
) {
1032 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1034 pfkey_send_delete(lcconf
->sock_pfkey
,
1035 ipsecdoi2pfkey_proto(pr
->proto_id
),
1037 iph2
->src
, iph2
->dst
, pr
->spi_p
/* pr->reqid_out */);
1044 ike_session_unlink_phase2(iph2
);
1048 ike_session_cleanup_ph2_stub (void *p
)
1051 ike_session_cleanup_ph2((phase2_handle_t
*)p
);
1055 ike_session_cleanup_other_established_ph2s (ike_session_t
*session
,
1056 phase2_handle_t
*new_iph2
)
1058 phase2_handle_t
*p
, *next
;
1060 if (!session
|| !new_iph2
|| session
!= new_iph2
->parent_session
|| new_iph2
->phase2_type
!= PHASE2_TYPE_SA
) {
1061 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1066 * if we are responder, then we should wait until the server sends a delete notification.
1068 if (session
->is_client
&& new_iph2
->side
== RESPONDER
) {
1072 LIST_FOREACH_SAFE(p
, &session
->ph2tree
, ph2ofsession_chain
, next
) {
1074 * TODO: currently, most recently established SA wins. Need to revisit to see if
1075 * alternative selections is better.
1077 if (p
!= new_iph2
&& p
->spid
== new_iph2
->spid
&& !p
->is_dying
) {
1082 plog(ASL_LEVEL_DEBUG
,
1083 "IPsec-SA needs to be deleted: %s\n",
1084 sadbsecas2str(p
->src
, p
->dst
,
1085 p
->satype
, p
->spid
, 0));
1087 if (p
->side
== INITIATOR
) {
1088 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1089 p
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, p
);
1091 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1092 p
->sce
= sched_new(5, ike_session_cleanup_ph2_stub
, p
);
1099 ike_session_stopped_by_controller (ike_session_t
*session
,
1103 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1106 if (session
->stop_timestamp
.tv_sec
||
1107 session
->stop_timestamp
.tv_usec
) {
1108 plog(ASL_LEVEL_DEBUG
, "already stopped %s.\n", __FUNCTION__
);
1111 session
->stopped_by_vpn_controller
= 1;
1112 gettimeofday(&session
->stop_timestamp
, NULL
);
1113 if (!session
->term_reason
) {
1114 session
->term_reason
= (__typeof__(session
->term_reason
))reason
;
1119 ike_sessions_stopped_by_controller (struct sockaddr_storage
*remote
,
1123 ike_session_t
*p
= NULL
;
1124 ike_session_t
*next_session
= NULL
;
1127 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1131 LIST_FOREACH_SAFE(p
, &ike_session_tree
, chain
, next_session
) {
1132 if ((withport
&& cmpsaddrstrict(&p
->session_id
.remote
, remote
) == 0) ||
1133 (!withport
&& cmpsaddrwop(&p
->session_id
.remote
, remote
) == 0)) {
1134 ike_session_stopped_by_controller(p
, reason
);
1140 ike_session_purge_ph2s_by_ph1 (phase1_handle_t
*iph1
)
1142 phase2_handle_t
*p
, *next
;
1144 if (!iph1
|| !iph1
->parent_session
) {
1145 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1149 LIST_FOREACH_SAFE(p
, &iph1
->parent_session
->ph2tree
, ph2ofsession_chain
, next
) {
1157 plog(ASL_LEVEL_DEBUG
,
1158 "IPsec-SA needs to be purged: %s\n",
1159 sadbsecas2str(p
->src
, p
->dst
,
1160 p
->satype
, p
->spid
, 0));
1162 ike_session_cleanup_ph2(p
);
1167 ike_session_update_ph2_ports (phase2_handle_t
*iph2
)
1169 struct sockaddr_storage
*local
;
1170 struct sockaddr_storage
*remote
;
1172 if (iph2
->parent_session
) {
1173 local
= &iph2
->parent_session
->session_id
.local
;
1174 remote
= &iph2
->parent_session
->session_id
.remote
;
1176 set_port(iph2
->src
, extract_port(local
));
1177 set_port(iph2
->dst
, extract_port(remote
));
1179 plog(ASL_LEVEL_DEBUG
, "invalid parent session in %s.\n", __FUNCTION__
);
1184 ike_session_get_sas_for_stats (ike_session_t
*session
,
1187 struct sastat
*stats
,
1188 u_int32_t max_stats
)
1191 phase2_handle_t
*iph2
;
1193 if (!session
|| !seq
|| !stats
|| !max_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1194 plog(ASL_LEVEL_DEBUG
, "invalid args in %s.\n", __FUNCTION__
);
1199 LIST_FOREACH(iph2
, &session
->ph2tree
, ph2ofsession_chain
) {
1200 if (iph2
->approval
) {
1203 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1204 if (pr
->ok
&& pr
->proto_id
== IPSECDOI_PROTO_IPSEC_ESP
) {
1208 if (dir
== IPSEC_DIR_INBOUND
) {
1209 stats
[found
].spi
= pr
->spi
;
1211 stats
[found
].spi
= pr
->spi_p
;
1213 if (++found
== max_stats
) {
1224 ike_session_update_traffic_idle_status (ike_session_t
*session
,
1226 struct sastat
*new_stats
,
1227 u_int32_t max_stats
)
1229 int i
, j
, found
= 0, idle
= 1;
1231 if (!session
|| !new_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1232 plog(ASL_LEVEL_DEBUG
, "invalid args in %s.\n", __FUNCTION__
);
1236 if (!session
->established
|| session
->stopped_by_vpn_controller
|| session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
) {
1237 plog(ASL_LEVEL_DEBUG
, "dropping update on invalid session in %s.\n", __FUNCTION__
);
1241 for (i
= 0; i
< max_stats
; i
++) {
1242 if (dir
== IPSEC_DIR_INBOUND
) {
1243 for (j
= 0; j
< session
->traffic_monitor
.num_in_last_poll
; j
++) {
1244 if (new_stats
[i
].spi
!= session
->traffic_monitor
.in_last_poll
[j
].spi
) {
1248 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.in_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1253 for (j
= 0; j
< session
->traffic_monitor
.num_out_last_poll
; j
++) {
1254 if (new_stats
[i
].spi
!= session
->traffic_monitor
.out_last_poll
[j
].spi
) {
1258 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.out_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1263 // new SA.... check for any activity
1265 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
) {
1266 plog(ASL_LEVEL_DEBUG
, "new SA: dir %d....\n", dir
);
1271 if (dir
== IPSEC_DIR_INBOUND
) {
1272 // overwrite old stats
1273 bzero(session
->traffic_monitor
.in_last_poll
, sizeof(session
->traffic_monitor
.in_last_poll
));
1274 bcopy(new_stats
, session
->traffic_monitor
.in_last_poll
, (max_stats
* sizeof(*new_stats
)));
1275 session
->traffic_monitor
.num_in_last_poll
= max_stats
;
1277 //plog(ASL_LEVEL_DEBUG, "peer sent data....\n");
1278 session
->peer_sent_data_sc_dpd
= 1;
1279 session
->peer_sent_data_sc_idle
= 1;
1282 // overwrite old stats
1283 bzero(session
->traffic_monitor
.out_last_poll
, sizeof(session
->traffic_monitor
.out_last_poll
));
1284 bcopy(new_stats
, session
->traffic_monitor
.out_last_poll
, (max_stats
* sizeof(*new_stats
)));
1285 session
->traffic_monitor
.num_out_last_poll
= max_stats
;
1287 //plog(ASL_LEVEL_DEBUG, "i sent data....\n");
1288 session
->i_sent_data_sc_dpd
= 1;
1289 session
->i_sent_data_sc_idle
= 1;
1293 session
->last_time_data_sc_detected
= time(NULL
);
1295 ike_session_monitor_idle(session
);
1299 ike_session_cleanup (ike_session_t
*session
,
1302 phase2_handle_t
*iph2
= NULL
;
1303 phase2_handle_t
*next_iph2
= NULL
;
1304 phase1_handle_t
*iph1
= NULL
;
1305 phase1_handle_t
*next_iph1
= NULL
;
1310 session
->is_dying
= 1;
1311 ike_session_stopped_by_controller(session
, reason
);
1313 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
1314 // do ph2's first... we need the ph1s for notifications
1315 LIST_FOREACH_SAFE(iph2
, &session
->ph2tree
, ph2ofsession_chain
, next_iph2
) {
1316 if (FSM_STATE_IS_ESTABLISHED(iph2
->status
)) {
1317 isakmp_info_send_d2(iph2
);
1319 isakmp_ph2expire(iph2
); // iph2 will go down 1 second later.
1322 // do the ph1s last.
1323 LIST_FOREACH_SAFE(iph1
, &session
->ph1tree
, ph1ofsession_chain
, next_iph1
) {
1324 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
)) {
1325 isakmp_info_send_d1(iph1
);
1327 isakmp_ph1expire(iph1
);
1330 // send ipsecManager a notification
1331 if (session
->is_cisco_ipsec
&& reason
&& reason
!= ike_session_stopped_by_vpn_disconnect
1332 && reason
!= ike_session_stopped_by_controller_comm_lost
) {
1334 if ((&session
->session_id
.remote
)->ss_family
== AF_INET
) {
1335 address
= ((struct sockaddr_in
*)&session
->session_id
.remote
)->sin_addr
.s_addr
;
1340 if (reason
== ike_session_stopped_by_idle
) {
1341 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT
, FROM_LOCAL
, address
, 0, NULL
);
1343 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_INTERNAL_ERROR
, FROM_LOCAL
, address
, 0, NULL
);
1349 ike_session_has_negoing_ph1 (ike_session_t
*session
)
1354 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1358 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
1359 if (!p
->is_dying
&& FSM_STATE_IS_NEGOTIATING(p
->status
)) {
1368 ike_session_has_established_ph1 (ike_session_t
*session
)
1373 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1377 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
1378 if (!p
->is_dying
&& FSM_STATE_IS_ESTABLISHED(p
->status
)) {
1387 ike_session_has_negoing_ph2 (ike_session_t
*session
)
1392 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1396 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
1397 if (!p
->is_dying
&& FSM_STATE_IS_NEGOTIATING(p
->status
)) {
1406 ike_session_has_established_ph2 (ike_session_t
*session
)
1411 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1415 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
1416 if (!p
->is_dying
&& FSM_STATE_IS_ESTABLISHED(p
->status
)) {
1425 ike_session_cleanup_ph1s_by_ph2 (phase2_handle_t
*iph2
)
1427 phase1_handle_t
*iph1
= NULL
;
1428 phase1_handle_t
*next_iph1
= NULL
;
1430 if (!iph2
|| !iph2
->parent_session
) {
1431 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1435 // phase1 is no longer useful
1436 LIST_FOREACH_SAFE(iph1
, &iph2
->parent_session
->ph1tree
, ph1ofsession_chain
, next_iph1
) {
1437 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
)) {
1438 isakmp_info_send_d1(iph1
);
1440 isakmp_ph1expire(iph1
);
1445 ike_session_is_client_ph2_rekey (phase2_handle_t
*iph2
)
1447 if (iph2
->parent_session
&&
1448 iph2
->parent_session
->is_client
&&
1450 iph2
->parent_session
->is_cisco_ipsec
) {
1457 ike_session_is_client_ph1_rekey (phase1_handle_t
*iph1
)
1459 if (iph1
->parent_session
&&
1460 iph1
->parent_session
->is_client
&&
1462 iph1
->parent_session
->is_cisco_ipsec
) {
1469 ike_session_is_client_ph1 (phase1_handle_t
*iph1
)
1471 if (iph1
->parent_session
&&
1472 iph1
->parent_session
->is_client
) {
1479 ike_session_is_client_ph2 (phase2_handle_t
*iph2
)
1481 if (iph2
->parent_session
&&
1482 iph2
->parent_session
->is_client
) {
1489 ike_session_start_xauth_timer (phase1_handle_t
*iph1
)
1491 // if there are no more established ph2s, start a timer to teardown the session
1492 if (iph1
->parent_session
&&
1493 iph1
->parent_session
->is_client
&&
1494 iph1
->parent_session
->is_cisco_ipsec
&&
1495 !iph1
->parent_session
->sc_xauth
) {
1496 iph1
->parent_session
->sc_xauth
= sched_new(300 /* 5 mins */,
1497 ike_session_cleanup_xauth_timeout
,
1498 iph1
->parent_session
);
1503 ike_session_stop_xauth_timer (phase1_handle_t
*iph1
)
1505 if (iph1
->parent_session
) {
1506 SCHED_KILL(iph1
->parent_session
->sc_xauth
);
1511 ike_session_is_id_ipany (vchar_t
*ext_id
)
1514 u_int8_t type
; /* ID Type */
1515 u_int8_t proto_id
; /* Protocol ID */
1516 u_int16_t port
; /* Port */
1517 u_int32_t addr
; /* IPv4 address */
1521 /* ignore protocol and port */
1522 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1523 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1524 id_ptr
->addr
== 0) {
1526 } else if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR_SUBNET
&&
1527 id_ptr
->mask
== 0 &&
1528 id_ptr
->addr
== 0) {
1531 plog(ASL_LEVEL_DEBUG
, "not ipany_ids in %s: type %d, addr %x, mask %x.\n",
1532 __FUNCTION__
, id_ptr
->type
, id_ptr
->addr
, id_ptr
->mask
);
1537 ike_session_is_id_portany (vchar_t
*ext_id
)
1540 u_int8_t type
; /* ID Type */
1541 u_int8_t proto_id
; /* Protocol ID */
1542 u_int16_t port
; /* Port */
1543 u_int32_t addr
; /* IPv4 address */
1548 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1549 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1550 id_ptr
->port
== 0) {
1553 plog(ASL_LEVEL_DEBUG
, "not portany_ids in %s: type %d, port %x.\n",
1554 __FUNCTION__
, id_ptr
->type
, id_ptr
->port
);
1559 ike_session_set_id_portany (vchar_t
*ext_id
)
1562 u_int8_t type
; /* ID Type */
1563 u_int8_t proto_id
; /* Protocol ID */
1564 u_int16_t port
; /* Port */
1565 u_int32_t addr
; /* IPv4 address */
1570 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1571 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
) {
1578 ike_session_cmp_ph2_ids_ipany (vchar_t
*ext_id
,
1581 if (ike_session_is_id_ipany(ext_id
) &&
1582 ike_session_is_id_ipany(ext_id_p
)) {
1589 * ipsec rekeys for l2tp-over-ipsec fail particularly when client is behind nat because the client's configs and policies don't
1590 * match the server's view of the client's address and port.
1591 * servers behave differently when using this address-port info to generate ids during phase2 rekeys, so try to match the incoming id to
1592 * a variety of info saved in the older phase2.
1595 ike_session_cmp_ph2_ids (phase2_handle_t
*iph2
,
1596 phase2_handle_t
*older_ph2
)
1598 vchar_t
*portany_id
= NULL
;
1599 vchar_t
*portany_id_p
= NULL
;
1601 if (iph2
->id
&& older_ph2
->id
&&
1602 iph2
->id
->l
== older_ph2
->id
->l
&&
1603 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1604 iph2
->id_p
&& older_ph2
->id_p
&&
1605 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1606 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1609 if (iph2
->ext_nat_id
&& older_ph2
->ext_nat_id
&&
1610 iph2
->ext_nat_id
->l
== older_ph2
->ext_nat_id
->l
&&
1611 memcmp(iph2
->ext_nat_id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->ext_nat_id
->l
) == 0 &&
1612 iph2
->ext_nat_id_p
&& older_ph2
->ext_nat_id_p
&&
1613 iph2
->ext_nat_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1614 memcmp(iph2
->ext_nat_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->ext_nat_id_p
->l
) == 0) {
1617 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1618 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1619 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1620 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1621 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1622 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1625 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1626 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1627 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1628 iph2
->id_p
&& older_ph2
->id_p
&&
1629 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1630 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1633 if (iph2
->id
&& older_ph2
->id
&&
1634 iph2
->id
->l
== older_ph2
->id
->l
&&
1635 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1636 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1637 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1638 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1642 /* check if the external id has a wildcard port and compare ids accordingly */
1643 if ((older_ph2
->ext_nat_id
&& ike_session_is_id_portany(older_ph2
->ext_nat_id
)) ||
1644 (older_ph2
->ext_nat_id_p
&& ike_session_is_id_portany(older_ph2
->ext_nat_id_p
))) {
1645 // try ignoring ports in iph2->id and iph2->id
1646 if (iph2
->id
&& (portany_id
= vdup(iph2
->id
))) {
1647 ike_session_set_id_portany(portany_id
);
1649 if (iph2
->id_p
&& (portany_id_p
= vdup(iph2
->id_p
))) {
1650 ike_session_set_id_portany(portany_id_p
);
1652 if (portany_id
&& older_ph2
->ext_nat_id
&&
1653 portany_id
->l
== older_ph2
->ext_nat_id
->l
&&
1654 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1655 portany_id_p
&& older_ph2
->ext_nat_id_p
&&
1656 portany_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1657 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1662 vfree(portany_id_p
);
1666 if (portany_id
&& iph2
->id
&& older_ph2
->ext_nat_id
&&
1667 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1668 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1669 iph2
->id_p
&& older_ph2
->id_p
&&
1670 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1671 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1676 vfree(portany_id_p
);
1680 if (portany_id_p
&& iph2
->id
&& older_ph2
->id
&&
1681 iph2
->id
->l
== older_ph2
->id
->l
&&
1682 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1683 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1684 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1685 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1690 vfree(portany_id_p
);
1698 vfree(portany_id_p
);
1705 ike_session_get_sainfo_r (phase2_handle_t
*iph2
)
1707 if (iph2
->parent_session
&&
1708 iph2
->parent_session
->is_client
&&
1709 iph2
->id
&& iph2
->id_p
) {
1711 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1712 plog(ASL_LEVEL_DEBUG
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1714 LIST_FOREACH(p
, &iph2
->parent_session
->ph2tree
, ph2ofsession_chain
) {
1715 if (iph2
!= p
&& !p
->is_dying
&& FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p
->status
) && p
->sainfo
) {
1716 plog(ASL_LEVEL_DEBUG
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1718 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1719 plog(ASL_LEVEL_DEBUG
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1720 iph2
->sainfo
= p
->sainfo
;
1722 retain_sainfo(iph2
->sainfo
);
1724 iph2
->spid
= p
->spid
;
1726 plog(ASL_LEVEL_DEBUG
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1728 if (p
->ext_nat_id
) {
1729 if (iph2
->ext_nat_id
) {
1730 vfree(iph2
->ext_nat_id
);
1732 iph2
->ext_nat_id
= vdup(p
->ext_nat_id
);
1734 if (p
->ext_nat_id_p
) {
1735 if (iph2
->ext_nat_id_p
) {
1736 vfree(iph2
->ext_nat_id_p
);
1738 iph2
->ext_nat_id_p
= vdup(p
->ext_nat_id_p
);
1749 ike_session_get_proposal_r (phase2_handle_t
*iph2
)
1751 if (iph2
->parent_session
&&
1752 iph2
->parent_session
->is_client
&&
1753 iph2
->id
&& iph2
->id_p
) {
1755 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1756 plog(ASL_LEVEL_DEBUG
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1758 LIST_FOREACH(p
, &iph2
->parent_session
->ph2tree
, ph2ofsession_chain
) {
1759 if (iph2
!= p
&& !p
->is_dying
&& FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p
->status
) &&
1761 plog(ASL_LEVEL_DEBUG
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1763 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1764 plog(ASL_LEVEL_DEBUG
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1765 iph2
->proposal
= dupsaprop(p
->approval
, 1);
1767 iph2
->spid
= p
->spid
;
1769 plog(ASL_LEVEL_DEBUG
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1780 ike_session_update_natt_version (phase1_handle_t
*iph1
)
1782 if (iph1
->parent_session
) {
1783 if (iph1
->natt_options
) {
1784 iph1
->parent_session
->natt_version
= iph1
->natt_options
->version
;
1786 iph1
->parent_session
->natt_version
= 0;
1792 ike_session_get_natt_version (phase1_handle_t
*iph1
)
1794 if (iph1
->parent_session
) {
1795 return(iph1
->parent_session
->natt_version
);
1801 ike_session_drop_rekey (ike_session_t
*session
, ike_session_rekey_type_t rekey_type
)
1804 if (session
->is_btmm_ipsec
&&
1805 session
->last_time_data_sc_detected
&&
1806 session
->traffic_monitor
.interv_mon
&&
1807 session
->traffic_monitor
.interv_idle
) {
1808 // for btmm: drop ph1/ph2 rekey if session is idle
1809 time_t now
= time(NULL
);
1811 if ((now
- session
->last_time_data_sc_detected
) > (session
->traffic_monitor
.interv_mon
<< 1)) {
1812 plog(ASL_LEVEL_DEBUG
, "btmm session is idle: drop ph%drekey.\n",
1816 } else if (!session
->is_btmm_ipsec
) {
1817 if (rekey_type
== IKE_SESSION_REKEY_TYPE_PH1
&&
1818 !ike_session_has_negoing_ph2(session
)) {
1819 // for vpn: only drop ph1 if there are no more ph2s.
1820 plog(ASL_LEVEL_DEBUG
, "vpn session is idle: drop ph1 rekey.\n");
1829 * this is called after racooon receives a 'kIOMessageSystemHasPoweredOn'
1830 * a lot is done to make sure that we don't sweep a session that's already been asserted.
1831 * however, it'll be too bad if the assertion comes after the session has already been swept.
1834 ike_session_sweep_sleepwake (void)
1836 ike_session_t
*p
= NULL
;
1837 ike_session_t
*next_session
= NULL
;
1839 // flag session as dying if all ph1/ph2 are dead/dying
1840 LIST_FOREACH_SAFE(p
, &ike_session_tree
, chain
, next_session
) {
1842 plog(ASL_LEVEL_DEBUG
, "skipping sweep of dying session.\n");
1845 SCHED_KILL(p
->sc_xauth
);
1846 if (p
->is_asserted
) {
1847 // for asserted session, traffic monitors will be restared after phase2 becomes established.
1848 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1849 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1850 plog(ASL_LEVEL_DEBUG
, "skipping sweep of asserted session.\n");
1854 // cleanup any stopped sessions as they will go down
1855 if (p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
1856 plog(ASL_LEVEL_DEBUG
, "sweeping stopped session.\n");
1857 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1861 if (!ike_session_has_established_ph1(p
) && !ike_session_has_established_ph2(p
)) {
1862 plog(ASL_LEVEL_DEBUG
, "session died while sleeping.\n");
1863 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1866 if (p
->traffic_monitor
.sc_mon
) {
1868 if (sched_get_time(p
->traffic_monitor
.sc_mon
, &xtime
)) {
1869 if (xtime
<= swept_at
) {
1870 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1871 if (!p
->is_dying
&& p
->traffic_monitor
.interv_mon
) {
1872 p
->traffic_monitor
.sc_mon
= sched_new(p
->traffic_monitor
.interv_mon
,
1873 ike_session_traffic_cop
,
1879 if (p
->traffic_monitor
.sc_idle
) {
1881 if (sched_get_time(p
->traffic_monitor
.sc_idle
, &xtime
)) {
1882 if (xtime
<= swept_at
) {
1883 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1884 if (!p
->is_dying
&& p
->traffic_monitor
.interv_idle
) {
1885 p
->traffic_monitor
.sc_idle
= sched_new(p
->traffic_monitor
.interv_idle
,
1886 ike_session_cleanup_idle
,
1896 * this is called after racooon receives an assert command from the controller/pppd.
1897 * this is intended to make racoon prepare to rekey both SAs because a network event occurred.
1898 * in the event of a sleepwake, the assert could happen before or after 'ike_session_sweep_sleepwake'.
1901 ike_session_assert_session (ike_session_t
*session
)
1903 phase2_handle_t
*iph2
= NULL
;
1904 phase2_handle_t
*iph2_next
= NULL
;
1905 phase1_handle_t
*iph1
= NULL
;
1906 phase1_handle_t
*iph1_next
= NULL
;
1908 if (!session
|| session
->is_dying
) {
1909 plog(ASL_LEVEL_DEBUG
, "Invalid parameters in %s.\n", __FUNCTION__
);
1913 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase2s
1914 LIST_FOREACH_SAFE(iph2
, &session
->ph2tree
, ph2ofsession_chain
, iph2_next
) {
1915 if (!iph2
->is_dying
&& !FSM_STATE_IS_EXPIRED(iph2
->status
)) {
1916 SCHED_KILL(iph2
->sce
);
1919 // delete SAs (in the kernel)
1920 if (FSM_STATE_IS_ESTABLISHED(iph2
->status
) && iph2
->approval
) {
1923 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1926 plog(ASL_LEVEL_DEBUG
,
1927 "Assert: Phase 2 %s deleted\n",
1928 sadbsecas2str(iph2
->src
, iph2
->dst
, iph2
->satype
, iph2
->spid
, ipsecdoi2pfkey_mode(pr
->encmode
)));
1930 pfkey_send_delete(lcconf
->sock_pfkey
,
1931 ipsecdoi2pfkey_proto(pr
->proto_id
),
1932 ipsecdoi2pfkey_mode(pr
->encmode
),
1933 iph2
->src
, iph2
->dst
, pr
->spi_p
);
1938 fsm_set_state(&iph2
->status
, IKEV1_STATE_PHASE2_EXPIRED
); // we want to delete SAs without telling the PEER
1939 iph2
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, iph2
);
1943 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase1s
1944 LIST_FOREACH_SAFE(iph1
, &session
->ph1tree
, ph1ofsession_chain
, iph1_next
) {
1945 if (!iph1
->is_dying
&& !FSM_STATE_IS_EXPIRED(iph1
->status
)) {
1946 SCHED_KILL(iph1
->sce
);
1947 SCHED_KILL(iph1
->sce_rekey
);
1951 plog(ASL_LEVEL_DEBUG
,
1952 "Assert: Phase 1 %s deleted\n",
1953 isakmp_pindex(&iph1
->index
, 0));
1955 ike_session_unbind_all_ph2_from_ph1(iph1
);
1957 fsm_set_state(&iph1
->status
, IKEV1_STATE_PHASE1_EXPIRED
); // we want to delete SAs without telling the PEER
1958 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
1959 iph1
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, iph1
);
1962 session
->is_asserted
= 1;
1968 ike_session_assert (struct sockaddr_storage
*local
,
1969 struct sockaddr_storage
*remote
)
1971 ike_session_t
*sess
;
1973 if (!local
|| !remote
) {
1974 plog(ASL_LEVEL_DEBUG
, "invalid parameters in %s.\n", __FUNCTION__
);
1978 if ((sess
= ike_session_get_session(local
, remote
, FALSE
))) {
1979 return(ike_session_assert_session(sess
));
1985 ike_session_ph2_retransmits (phase2_handle_t
*iph2
)
1987 int num_retransmits
;
1989 if (!iph2
->is_dying
&&
1992 iph2
->ph1
->sce_rekey
&& !sched_is_dead(iph2
->ph1
->sce_rekey
) &&
1993 iph2
->side
== INITIATOR
&&
1994 iph2
->parent_session
&&
1995 !iph2
->parent_session
->is_cisco_ipsec
&& /* not for Cisco */
1996 iph2
->parent_session
->is_client
) {
1997 num_retransmits
= iph2
->ph1
->rmconf
->retry_counter
- iph2
->retry_counter
;
1998 if (num_retransmits
== 3) {
2000 * phase2 negotiation is stalling on retransmits, inspite of a valid ph1.
2001 * one of the following is possible:
2002 * - (0) severe packet loss.
2003 * - (1) the peer is dead.
2004 * - (2) the peer is out of sync hence dropping this phase2 rekey (and perhaps responding with insecure
2005 * invalid-cookie notifications... but those are untrusted and so we can't rekey phase1 off that)
2006 * (2.1) the peer rebooted (or process restarted) and is now alive.
2007 * (2.2) the peer has deleted phase1 without notifying us (or the notification got dropped somehow).
2008 * (2.3) the peer has a policy/bug stopping this phase2 rekey
2010 * in all these cases, one sure way to know is to trigger a phase1 rekey early.
2012 plog(ASL_LEVEL_DEBUG
, "Many Phase 2 retransmits: try Phase 1 rekey and this Phase 2 to quit earlier.\n");
2013 isakmp_ph1rekeyexpire(iph2
->ph1
, TRUE
);
2014 iph2
->retry_counter
= 0;
2020 ike_session_ph1_retransmits (phase1_handle_t
*iph1
)
2022 int num_retransmits
;
2024 if (!iph1
->is_dying
&&
2027 FSM_STATE_IS_NEGOTIATING(iph1
->status
) &&
2028 iph1
->side
== INITIATOR
&&
2029 iph1
->parent_session
&&
2030 iph1
->parent_session
->is_client
&&
2031 !ike_session_has_other_negoing_ph1(iph1
->parent_session
, iph1
)) {
2032 num_retransmits
= iph1
->rmconf
->retry_counter
- iph1
->retry_counter
;
2033 if (num_retransmits
== 3) {
2034 plog(ASL_LEVEL_DEBUG
, "Many Phase 1 retransmits: try quit earlier.\n");
2035 iph1
->retry_counter
= 0;
2041 ike_session_bindph12(phase1_handle_t
*iph1
, phase2_handle_t
*iph2
)
2044 plog(ASL_LEVEL_ERR
, "Phase 2 already bound %s.\n", __FUNCTION__
);
2047 LIST_INSERT_HEAD(&iph1
->bound_ph2tree
, iph2
, ph1bind_chain
);
2051 ike_session_unbindph12(phase2_handle_t
*iph2
)
2053 if (iph2
->ph1
!= NULL
) {
2055 LIST_REMOVE(iph2
, ph1bind_chain
);
2060 ike_session_rebindph12(phase1_handle_t
*new_ph1
, phase2_handle_t
*iph2
)
2066 // reconcile the ph1-to-ph2 binding
2067 ike_session_unbindph12(iph2
);
2068 ike_session_bindph12(new_ph1
, iph2
);
2069 // recalculate ivm since ph1 binding has changed
2070 if (iph2
->ivm
!= NULL
) {
2071 oakley_delivm(iph2
->ivm
);
2072 if (FSM_STATE_IS_ESTABLISHED(new_ph1
->status
)) {
2073 iph2
->ivm
= oakley_newiv2(new_ph1
, iph2
->msgid
);
2074 plog(ASL_LEVEL_DEBUG
, "Phase 1-2 binding changed... recalculated ivm.\n");
2082 ike_session_unbind_all_ph2_from_ph1 (phase1_handle_t
*iph1
)
2084 phase2_handle_t
*p
= NULL
;
2085 phase2_handle_t
*next
= NULL
;
2087 LIST_FOREACH_SAFE(p
, &iph1
->bound_ph2tree
, ph1bind_chain
, next
) {
2088 ike_session_unbindph12(p
);
2093 ike_session_rebind_all_ph12_to_new_ph1 (phase1_handle_t
*old_iph1
,
2094 phase1_handle_t
*new_iph1
)
2096 phase2_handle_t
*p
= NULL
;
2097 phase2_handle_t
*next
= NULL
;
2099 if (old_iph1
== new_iph1
|| !old_iph1
|| !new_iph1
) {
2100 plog(ASL_LEVEL_DEBUG
, "Invalid parameters in %s.\n", __FUNCTION__
);
2104 if (old_iph1
->parent_session
!= new_iph1
->parent_session
) {
2105 plog(ASL_LEVEL_DEBUG
, "Invalid parent sessions in %s.\n", __FUNCTION__
);
2109 LIST_FOREACH_SAFE(p
, &old_iph1
->bound_ph2tree
, ph1bind_chain
, next
) {
2110 if (p
->parent_session
!= new_iph1
->parent_session
) {
2111 plog(ASL_LEVEL_ERR
, "Mismatched parent session in ph1bind replacement.\n");
2113 if (p
->ph1
== new_iph1
) {
2114 plog(ASL_LEVEL_ERR
, "Same Phase 2 in ph1bind replacement in %s.\n",__FUNCTION__
);
2116 ike_session_rebindph12(new_iph1
, p
);