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 "isakmp_inf.h"
46 #include "localconf.h"
47 #include "remoteconf.h"
48 #include "vpn_control.h"
49 #include "vpn_control_var.h"
52 #include "power_mgmt.h"
54 #define GET_SAMPLE_PERIOD(s,m) do { \
64 const char *ike_session_stopped_by_vpn_disconnect
= "Stopped by VPN disconnect";
65 const char *ike_session_stopped_by_controller_comm_lost
= "Stopped by loss of controller communication";
66 const char *ike_session_stopped_by_flush
= "Stopped by Flush";
67 const char *ike_session_stopped_by_idle
= "Stopped by Idle";
68 const char *ike_session_stopped_by_xauth_timeout
= "Stopped by XAUTH timeout";
69 const char *ike_session_stopped_by_sleepwake
= "Stopped by Sleep-Wake";
70 const char *ike_session_stopped_by_assert
= "Stopped by Assert";
71 const char *ike_session_stopped_by_peer
= "Stopped by Peer";
73 LIST_HEAD(_ike_session_tree_
, ike_session
) ike_session_tree
= { NULL
};
75 static void ike_session_bindph12(phase1_handle_t
*, phase2_handle_t
*);
76 static void ike_session_rebindph12(phase1_handle_t
*, phase2_handle_t
*);
77 static void ike_session_unbind_all_ph2_from_ph1 (phase1_handle_t
*);
78 static void ike_session_rebind_all_ph12_to_new_ph1 (phase1_handle_t
*, phase1_handle_t
*);
80 static ike_session_t
*
81 new_ike_session (ike_session_id_t
*id
)
83 ike_session_t
*session
;
86 plog(ASL_LEVEL_ERR
, "Invalid parameters in %s.\n", __FUNCTION__
);
90 session
= racoon_calloc(1, sizeof(*session
));
92 bzero(session
, sizeof(*session
));
93 memcpy(&session
->session_id
, id
, sizeof(*id
));
94 LIST_INIT(&session
->ph1tree
);
95 LIST_INIT(&session
->ph2tree
);
96 LIST_INSERT_HEAD(&ike_session_tree
, session
, chain
);
102 free_ike_session (ike_session_t
*session
)
104 int is_failure
= TRUE
;
106 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
107 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
108 SCHED_KILL(session
->sc_xauth
);
109 if (session
->start_timestamp
.tv_sec
|| session
->start_timestamp
.tv_usec
) {
110 if (!(session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
)) {
111 gettimeofday(&session
->stop_timestamp
, NULL
);
113 if (session
->term_reason
!= ike_session_stopped_by_vpn_disconnect
||
114 session
->term_reason
!= ike_session_stopped_by_controller_comm_lost
||
115 session
->term_reason
!= ike_session_stopped_by_flush
||
116 session
->term_reason
!= ike_session_stopped_by_idle
) {
120 // do MessageTracer cleanup here
121 plog(ASL_LEVEL_NOTICE
,
122 "Freeing IKE-Session to %s.\n",
123 saddr2str((struct sockaddr
*)&session
->session_id
.remote
));
124 LIST_REMOVE(session
, chain
);
125 racoon_free(session
);
131 ike_session_init (void)
133 LIST_INIT(&ike_session_tree
);
137 ike_session_get_rekey_lifetime (int local_spi_is_higher
, u_int expiry_lifetime
)
139 u_int rekey_lifetime
= expiry_lifetime
/ 10;
141 if (rekey_lifetime
) {
142 if (local_spi_is_higher
) {
143 return (rekey_lifetime
* 9);
145 return (rekey_lifetime
* 8);
148 if (local_spi_is_higher
) {
149 rekey_lifetime
= expiry_lifetime
- 1;
151 rekey_lifetime
= expiry_lifetime
- 2;
154 if (rekey_lifetime
< expiry_lifetime
) {
155 return rekey_lifetime
;
161 ike_session_create_session (ike_session_id_t
*session_id
)
166 plog(ASL_LEVEL_NOTICE
, "New IKE Session to %s.\n", saddr2str((struct sockaddr
*)&session_id
->remote
));
168 return new_ike_session(session_id
);
172 ike_session_release_session (ike_session_t
*session
)
174 while (!LIST_EMPTY(&session
->ph2tree
)) {
175 phase2_handle_t
*phase2
= LIST_FIRST(&session
->ph2tree
);
176 ike_session_unlink_phase2(phase2
);
179 while (!LIST_EMPTY(&session
->ph1tree
)) {
180 phase1_handle_t
*phase1
= LIST_FIRST(&session
->ph1tree
);
181 ike_session_unlink_phase1(phase1
);
185 // %%%%%%%%% re-examine this - keep both floated and unfloated port when behind nat
187 ike_session_get_session (struct sockaddr_storage
*local
,
188 struct sockaddr_storage
*remote
,
190 isakmp_index
*optionalIndex
)
192 ike_session_t
*p
= NULL
;
194 ike_session_id_t id_default
;
195 ike_session_id_t id_floated_default
;
196 ike_session_id_t id_wop
;
197 ike_session_t
*best_match
= NULL
;
198 u_int16_t remote_port
;
199 int is_isakmp_remote_port
;
201 if (!local
|| !remote
) {
202 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
206 remote_port
= extract_port(remote
);
207 if (remote_port
&& remote_port
!= PORT_ISAKMP
&& remote_port
!= PORT_ISAKMP_NATT
) {
208 is_isakmp_remote_port
= 0;
210 is_isakmp_remote_port
= 1;
213 /* 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 */
214 bzero(&id
, sizeof(id
));
215 bzero(&id_default
, sizeof(id_default
));
216 bzero(&id_floated_default
, sizeof(id_floated_default
));
217 bzero(&id_wop
, sizeof(id_wop
));
218 if (local
->ss_family
== AF_INET
) {
219 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in
));
220 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in
));
221 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in
));
222 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in
));
223 } else if (local
->ss_family
== AF_INET6
) {
224 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in6
));
225 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in6
));
226 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in6
));
227 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in6
));
229 set_port(&id_default
.local
, PORT_ISAKMP
);
230 set_port(&id_floated_default
.local
, PORT_ISAKMP_NATT
);
231 set_port(&id_wop
.local
, 0);
232 if (remote
->ss_family
== AF_INET
) {
233 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in
));
234 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in
));
235 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in
));
236 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in
));
237 } else if (remote
->ss_family
== AF_INET6
) {
238 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in6
));
239 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
240 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
241 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in6
));
243 set_port(&id_default
.remote
, PORT_ISAKMP
);
244 set_port(&id_floated_default
.remote
, PORT_ISAKMP_NATT
);
245 set_port(&id_wop
.remote
, 0);
247 plog(ASL_LEVEL_DEBUG
,
248 "start search for IKE-Session. target %s.\n",
249 saddr2str((struct sockaddr
*)remote
));
251 LIST_FOREACH(p
, &ike_session_tree
, chain
) {
252 plog(ASL_LEVEL_DEBUG
,
253 "still search for IKE-Session. this %s.\n",
254 saddr2str((struct sockaddr
*)&p
->session_id
.remote
));
256 // for now: ignore any stopped sessions as they will go down
257 if (p
->is_dying
|| p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
258 plog(ASL_LEVEL_DEBUG
, "still searching. skipping... session to %s is already stopped, active ph1 %d ph2 %d.\n",
259 saddr2str((struct sockaddr
*)&p
->session_id
.remote
),
260 p
->ikev1_state
.active_ph1cnt
, p
->ikev1_state
.active_ph2cnt
);
264 // Skip if the spi doesn't match
265 if (optionalIndex
!= NULL
&& ike_session_getph1byindex(p
, optionalIndex
) == NULL
) {
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) {
286 } else if (optionalIndex
!= NULL
) {
287 // If the SPI did match, this one counts as a best match
292 plog(ASL_LEVEL_DEBUG
,
293 "Best-match IKE-Session to %s.\n",
294 saddr2str((struct sockaddr
*)&best_match
->session_id
.remote
));
297 if (alloc_if_absent
) {
298 plog(ASL_LEVEL_DEBUG
,
299 "New IKE-Session to %s.\n",
300 saddr2str((struct sockaddr
*)&id
.remote
));
301 return new_ike_session(&id
);
308 ike_session_init_traffic_cop_params (phase1_handle_t
*iph1
)
312 (!iph1
->rmconf
->idle_timeout
&& !iph1
->rmconf
->dpd_interval
)) {
316 if (!iph1
->parent_session
->traffic_monitor
.interv_idle
) {
317 iph1
->parent_session
->traffic_monitor
.interv_idle
= iph1
->rmconf
->idle_timeout
;
320 if (!iph1
->parent_session
->traffic_monitor
.dir_idle
) {
321 iph1
->parent_session
->traffic_monitor
.dir_idle
= iph1
->rmconf
->idle_timeout_dir
;
324 if (!iph1
->parent_session
->traffic_monitor
.interv_mon
) {
325 int min_period
, max_period
, sample_period
= 0;
327 /* calculate the sampling interval... half the smaller interval */
328 if (iph1
->rmconf
->dpd_interval
&&
329 (iph1
->rmconf
->dpd_algo
== DPD_ALGO_INBOUND_DETECT
||
330 iph1
->rmconf
->dpd_algo
== DPD_ALGO_BLACKHOLE_DETECT
)) {
331 // when certain types of dpd are enabled
332 min_period
= MIN(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
333 max_period
= MAX(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
334 } else if (iph1
->rmconf
->idle_timeout
) {
335 min_period
= max_period
= iph1
->rmconf
->idle_timeout
;
337 // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic
341 GET_SAMPLE_PERIOD(sample_period
, min_period
);
343 GET_SAMPLE_PERIOD(sample_period
, max_period
);
345 iph1
->parent_session
->traffic_monitor
.interv_mon
= sample_period
;
350 ike_session_update_mode (phase2_handle_t
*iph2
)
352 if (!iph2
|| !iph2
->parent_session
) {
355 if (iph2
->phase2_type
!= PHASE2_TYPE_SA
)
358 // exit early if we already detected cisco-ipsec
359 if (iph2
->parent_session
->is_cisco_ipsec
) {
363 if (iph2
->approval
) {
364 if (!ipsecdoi_any_transportmode(iph2
->approval
)) {
365 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
366 iph2
->parent_session
->is_cisco_ipsec
= 0;
367 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
368 iph2
->parent_session
->is_btmm_ipsec
= 1;
370 } else if (ipsecdoi_transportmode(iph2
->approval
)) {
371 iph2
->parent_session
->is_cisco_ipsec
= 0;
372 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
373 iph2
->parent_session
->is_btmm_ipsec
= 0;
376 } else if (iph2
->proposal
) {
377 if (!ipsecdoi_any_transportmode(iph2
->proposal
)) {
378 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
379 iph2
->parent_session
->is_cisco_ipsec
= 0;
380 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
381 iph2
->parent_session
->is_btmm_ipsec
= 1;
383 } else if (ipsecdoi_transportmode(iph2
->proposal
)) {
384 iph2
->parent_session
->is_cisco_ipsec
= 0;
385 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
386 iph2
->parent_session
->is_btmm_ipsec
= 0;
393 ike_session_cleanup_xauth_timeout (void *arg
)
395 ike_session_t
*session
= (ike_session_t
*)arg
;
397 SCHED_KILL(session
->sc_xauth
);
398 // if there are no more established ph2s, start a timer to teardown the session
399 if (!ike_session_has_established_ph2(session
)) {
400 ike_session_cleanup(session
, ike_session_stopped_by_xauth_timeout
);
402 session
->sc_xauth
= sched_new(300 /* 5 mins */,
403 ike_session_cleanup_xauth_timeout
,
409 ike_session_link_phase1 (ike_session_t
*session
, phase1_handle_t
*iph1
)
412 if (!session
|| !iph1
) {
413 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
417 gettimeofday(&session
->start_timestamp
, NULL
);
419 if (iph1
->started_by_api
) {
420 session
->is_cisco_ipsec
= 1;
421 session
->is_l2tpvpn_ipsec
= 0;
422 session
->is_btmm_ipsec
= 0;
424 iph1
->parent_session
= session
;
425 LIST_INSERT_HEAD(&session
->ph1tree
, iph1
, ph1ofsession_chain
);
426 session
->ikev1_state
.active_ph1cnt
++;
427 if ((!session
->ikev1_state
.ph1cnt
&&
428 iph1
->side
== INITIATOR
) ||
429 iph1
->started_by_api
) {
430 // client initiates the first phase1 or, is started by controller api
431 session
->is_client
= 1;
433 if (session
->established
&&
434 session
->ikev1_state
.ph1cnt
&&
435 iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
438 session
->ikev1_state
.ph1cnt
++;
439 ike_session_init_traffic_cop_params(iph1
);
445 ike_session_link_phase2 (ike_session_t
*session
, phase2_handle_t
*iph2
)
448 plog(ASL_LEVEL_ERR
, "Invalid parameters in %s.\n", __FUNCTION__
);
451 if (iph2
->parent_session
) {
452 plog(ASL_LEVEL_ERR
, "Phase 2 already linked to session %s.\n", __FUNCTION__
);
455 iph2
->parent_session
= session
;
456 LIST_INSERT_HEAD(&session
->ph2tree
, iph2
, ph2ofsession_chain
);
457 session
->ikev1_state
.active_ph2cnt
++;
458 if (!session
->ikev1_state
.ph2cnt
&&
459 iph2
->side
== INITIATOR
) {
460 // client initiates the first phase2
461 session
->is_client
= 1;
463 if (iph2
->phase2_type
== PHASE2_TYPE_SA
&&
464 session
->established
&&
465 session
->ikev1_state
.ph2cnt
&&
466 iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
469 session
->ikev1_state
.ph2cnt
++;
470 ike_session_update_mode(iph2
);
476 ike_session_link_ph2_to_ph1 (phase1_handle_t
*iph1
, phase2_handle_t
*iph2
)
478 struct sockaddr_storage
*local
;
479 struct sockaddr_storage
*remote
;
483 plog(ASL_LEVEL_ERR
, "Invalid parameters in %s.\n", __FUNCTION__
);
487 plog(ASL_LEVEL_ERR
, "Phase 2 already linked %s.\n", __FUNCTION__
);
488 if (iph2
->ph1
== iph1
)
491 return -1; // This shouldn't happen
497 if (iph2
->parent_session
== NULL
)
498 if ((error
= ike_session_link_phase2(iph1
->parent_session
, iph2
)))
501 ike_session_bindph12(iph1
, iph2
);
506 ike_session_unlink_phase1 (phase1_handle_t
*iph1
)
508 ike_session_t
*session
;
510 if (!iph1
|| !iph1
->parent_session
) {
511 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
515 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
516 if (LIST_FIRST(&iph1
->bound_ph2tree
)) {
517 // reparent any phase2 that may be hanging on to this phase1
518 ike_session_update_ph1_ph2tree(iph1
);
522 sched_scrub_param(iph1
);
523 session
= iph1
->parent_session
;
524 LIST_REMOVE(iph1
, ph1ofsession_chain
);
525 iph1
->parent_session
= NULL
;
526 session
->ikev1_state
.active_ph1cnt
--;
527 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
528 session
->is_dying
= 1;
529 free_ike_session(session
);
531 ike_session_delph1(iph1
);
536 ike_session_unlink_phase2 (phase2_handle_t
*iph2
)
538 ike_session_t
*session
;
540 if (!iph2
|| !iph2
->parent_session
) {
541 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
544 sched_scrub_param(iph2
);
545 ike_session_unbindph12(iph2
);
547 LIST_REMOVE(iph2
, ph2ofsession_chain
);
548 session
= iph2
->parent_session
;
549 iph2
->parent_session
= NULL
;
550 session
->ikev1_state
.active_ph2cnt
--;
551 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
552 session
->is_dying
= 1;
553 free_ike_session(session
);
555 ike_session_delph2(iph2
);
561 ike_session_update_ph1_ph2tree (phase1_handle_t
*iph1
)
563 phase1_handle_t
*new_iph1
= NULL
;
566 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
570 if (iph1
->parent_session
) {
571 new_iph1
= ike_session_get_established_ph1(iph1
->parent_session
);
574 plog(ASL_LEVEL_NOTICE
, "no ph1bind replacement found. NULL ph1.\n");
575 ike_session_unbind_all_ph2_from_ph1(iph1
);
576 } else if (iph1
== new_iph1
) {
577 plog(ASL_LEVEL_NOTICE
, "no ph1bind replacement found. same ph1.\n");
578 ike_session_unbind_all_ph2_from_ph1(iph1
);
580 ike_session_rebind_all_ph12_to_new_ph1(iph1
, new_iph1
);
583 plog(ASL_LEVEL_NOTICE
, "invalid parent session in %s.\n", __FUNCTION__
);
589 ike_session_update_ph2_ph1bind (phase2_handle_t
*iph2
)
591 phase1_handle_t
*iph1
;
593 if (!iph2
|| iph2
->phase2_type
!= PHASE2_TYPE_SA
) {
594 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
598 iph1
= ike_session_get_established_ph1(iph2
->parent_session
);
599 if (iph1
&& iph2
->ph1
&& iph1
!= iph2
->ph1
) {
600 ike_session_rebindph12(iph1
, iph2
);
601 } else if (iph1
&& !iph2
->ph1
) {
602 ike_session_bindph12(iph1
, iph2
);
609 ike_session_get_established_or_negoing_ph1 (ike_session_t
*session
)
611 phase1_handle_t
*p
, *iph1
= NULL
;
614 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
618 // look for the most mature ph1 under the session
619 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
620 if (!p
->is_dying
&& (FSM_STATE_IS_ESTABLISHED(p
->status
) || FSM_STATE_IS_NEGOTIATING(p
->status
))) {
621 if (!iph1
|| p
->status
> iph1
->status
) {
623 } else if (iph1
&& p
->status
== iph1
->status
) {
624 // TODO: pick better one based on farthest rekey/expiry remaining
633 ike_session_get_established_ph1 (ike_session_t
*session
)
638 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
642 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
643 if (!p
->is_dying
&& FSM_STATE_IS_ESTABLISHED(p
->status
)) {
653 ike_session_has_other_established_ph1 (ike_session_t
*session
, phase1_handle_t
*iph1
)
661 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
662 if (iph1
!= p
&& !p
->is_dying
) {
663 if (FSM_STATE_IS_ESTABLISHED(p
->status
) && p
->sce_rekey
) {
673 ike_session_has_other_negoing_ph1 (ike_session_t
*session
, phase1_handle_t
*iph1
)
678 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
682 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
683 if (iph1
!= p
&& !p
->is_dying
) {
684 if (FSM_STATE_IS_NEGOTIATING(p
->status
)) {
694 ike_session_has_other_established_ph2 (ike_session_t
*session
, phase2_handle_t
*iph2
)
699 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
703 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
704 if (p
->phase2_type
== PHASE2_TYPE_SA
&& iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
705 if (FSM_STATE_IS_ESTABLISHED(p
->status
)) {
715 ike_session_has_other_negoing_ph2 (ike_session_t
*session
, phase2_handle_t
*iph2
)
720 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
724 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
725 plog(ASL_LEVEL_DEBUG
, "%s: ph2 sub spid %d, db spid %d\n", __FUNCTION__
, iph2
->spid
, p
->spid
);
726 if (p
->phase2_type
== PHASE2_TYPE_SA
&& iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
727 if (FSM_STATE_IS_NEGOTIATING(p
->status
)) {
738 ike_session_ikev1_float_ports (phase1_handle_t
*iph1
)
740 struct sockaddr_storage
*local
, *remote
;
743 if (iph1
->parent_session
) {
744 local
= &iph1
->parent_session
->session_id
.local
;
745 remote
= &iph1
->parent_session
->session_id
.remote
;
747 set_port(local
, extract_port(iph1
->local
));
748 set_port(remote
, extract_port(iph1
->remote
));
749 iph1
->parent_session
->ports_floated
= 1;
751 LIST_FOREACH(p
, &iph1
->parent_session
->ph2tree
, ph2ofsession_chain
) {
756 set_port(local
, extract_port(iph1
->local
));
757 set_port(remote
, extract_port(iph1
->remote
));
760 plog(ASL_LEVEL_NOTICE
, "invalid parent session in %s.\n", __FUNCTION__
);
765 ike_session_traffic_cop (void *arg
)
767 ike_session_t
*session
= (__typeof__(session
))arg
;
770 (session
->established
&& !session
->stopped_by_vpn_controller
&& !session
->stop_timestamp
.tv_sec
&& !session
->stop_timestamp
.tv_usec
)) {
771 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
772 /* get traffic query from kernel */
773 if (pk_sendget_inbound_sastats(session
) < 0) {
775 plog(ASL_LEVEL_NOTICE
, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__
);
777 if (pk_sendget_outbound_sastats(session
) < 0) {
779 plog(ASL_LEVEL_NOTICE
, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__
);
781 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
782 ike_session_traffic_cop
,
786 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
791 ike_session_cleanup_idle (void *arg
)
793 ike_session_cleanup((ike_session_t
*)arg
, ike_session_stopped_by_idle
);
797 ike_session_monitor_idle (ike_session_t
*session
)
802 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_INBOUND
||
803 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
804 if (session
->peer_sent_data_sc_idle
) {
805 plog(ASL_LEVEL_NOTICE
, "%s: restart idle-timeout because peer sent data. monitoring dir %d. idle timer %d s\n",
806 __FUNCTION__
, session
->traffic_monitor
.dir_idle
, session
->traffic_monitor
.interv_idle
);
807 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
808 if (session
->traffic_monitor
.interv_idle
) {
809 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
810 ike_session_cleanup_idle
,
813 session
->peer_sent_data_sc_idle
= 0;
814 session
->i_sent_data_sc_idle
= 0;
818 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_OUTBOUND
||
819 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
820 if (session
->i_sent_data_sc_idle
) {
821 plog(ASL_LEVEL_NOTICE
, "%s: restart idle-timeout because i sent data. monitoring dir %d. idle times %d s\n",
822 __FUNCTION__
, session
->traffic_monitor
.dir_idle
, session
->traffic_monitor
.interv_idle
);
823 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
824 if (session
->traffic_monitor
.interv_idle
) {
825 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
826 ike_session_cleanup_idle
,
829 session
->peer_sent_data_sc_idle
= 0;
830 session
->i_sent_data_sc_idle
= 0;
837 ike_session_start_traffic_mon (ike_session_t
*session
)
839 if (session
->traffic_monitor
.interv_mon
) {
840 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
841 ike_session_traffic_cop
,
844 if (session
->traffic_monitor
.interv_idle
) {
845 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
846 ike_session_cleanup_idle
,
852 ike_session_ph2_established (phase2_handle_t
*iph2
)
854 if (!iph2
->parent_session
|| iph2
->phase2_type
!= PHASE2_TYPE_SA
) {
855 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
858 SCHED_KILL(iph2
->parent_session
->sc_xauth
);
859 if (!iph2
->parent_session
->established
) {
860 gettimeofday(&iph2
->parent_session
->estab_timestamp
, NULL
);
861 iph2
->parent_session
->established
= 1;
862 ike_session_start_traffic_mon(iph2
->parent_session
);
863 } else if (iph2
->parent_session
->is_asserted
) {
864 ike_session_start_traffic_mon(iph2
->parent_session
);
866 iph2
->parent_session
->is_asserted
= 0;
867 // nothing happening to this session
868 iph2
->parent_session
->term_reason
= NULL
;
870 ike_session_update_mode(iph2
);
871 if (iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV1
)
872 ike_session_unbindph12(iph2
);
874 #ifdef ENABLE_VPNCONTROL_PORT
875 vpncontrol_notify_peer_resp_ph2(1, iph2
);
876 #endif /* ENABLE_VPNCONTROL_PORT */
877 plog(ASL_LEVEL_NOTICE
, "%s: ph2 established, spid %d\n", __FUNCTION__
, iph2
->spid
);
881 ike_session_cleanup_ph1 (phase1_handle_t
*iph1
)
883 if (FSM_STATE_IS_EXPIRED(iph1
->status
)) {
884 // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL
885 iph1
->sce
= sched_new(1, isakmp_ph1delete_stub
, iph1
);
889 /* send delete information */
890 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
)) {
891 isakmp_info_send_d1(iph1
);
894 isakmp_ph1expire(iph1
);
898 ike_session_cleanup_ph1_stub (void *p
)
901 ike_session_cleanup_ph1((phase1_handle_t
*)p
);
905 ike_session_replace_other_ph1 (phase1_handle_t
*new_iph1
,
906 phase1_handle_t
*old_iph1
)
908 char *local
, *remote
, *index
;
909 ike_session_t
*session
= NULL
;
912 session
= new_iph1
->parent_session
;
914 if (!session
|| !new_iph1
|| !old_iph1
|| session
!= old_iph1
->parent_session
|| new_iph1
== old_iph1
) {
915 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
920 * if we are responder, then we should wait until the server sends a delete notification.
922 if (session
->is_client
&&
923 new_iph1
->side
== RESPONDER
) {
927 SCHED_KILL(old_iph1
->sce
);
928 SCHED_KILL(old_iph1
->sce_rekey
);
929 old_iph1
->is_dying
= 1;
932 local
= racoon_strdup(saddr2str((struct sockaddr
*)old_iph1
->local
));
933 remote
= racoon_strdup(saddr2str((struct sockaddr
*)old_iph1
->remote
));
934 index
= racoon_strdup(isakmp_pindex(&old_iph1
->index
, 0));
936 STRDUP_FATAL(remote
);
938 plog(ASL_LEVEL_NOTICE
, "ISAKMP-SA %s-%s (spi:%s) needs to be deleted, replaced by (spi:%s)\n", local
, remote
, index
, isakmp_pindex(&new_iph1
->index
, 0));
943 // first rebind the children ph2s of this dying ph1 to the new ph1.
944 ike_session_rebind_all_ph12_to_new_ph1 (old_iph1
, new_iph1
);
946 if (old_iph1
->side
== INITIATOR
) {
947 /* everyone deletes old outbound SA */
948 old_iph1
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, old_iph1
);
950 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
951 old_iph1
->sce
= sched_new(7, ike_session_cleanup_ph1_stub
, old_iph1
);
956 ike_session_cleanup_other_established_ph1s (ike_session_t
*session
,
957 phase1_handle_t
*new_iph1
)
959 phase1_handle_t
*p
, *next
;
960 char *local
, *remote
;
962 if (!session
|| !new_iph1
|| session
!= new_iph1
->parent_session
) {
963 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
968 * if we are responder, then we should wait until the server sends a delete notification.
970 if (session
->is_client
&&
971 new_iph1
->side
== RESPONDER
) {
975 LIST_FOREACH_SAFE(p
, &session
->ph1tree
, ph1ofsession_chain
, next
) {
977 * TODO: currently, most recently established SA wins. Need to revisit to see if
978 * alternative selections is better (e.g. largest p->index stays).
980 if (p
!= new_iph1
&& !p
->is_dying
) {
982 SCHED_KILL(p
->sce_rekey
);
986 local
= racoon_strdup(saddr2str((struct sockaddr
*)p
->local
));
987 remote
= racoon_strdup(saddr2str((struct sockaddr
*)p
->remote
));
989 STRDUP_FATAL(remote
);
990 plog(ASL_LEVEL_NOTICE
,
991 "ISAKMP-SA needs to be deleted %s-%s spi:%s\n",
992 local
, remote
, isakmp_pindex(&p
->index
, 0));
996 // first rebind the children ph2s of this dying ph1 to the new ph1.
997 ike_session_rebind_all_ph12_to_new_ph1 (p
, new_iph1
);
999 if (p
->side
== INITIATOR
) {
1000 /* everyone deletes old outbound SA */
1001 p
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, p
);
1003 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
1004 p
->sce
= sched_new(7, ike_session_cleanup_ph1_stub
, p
);
1011 ike_session_cleanup_ph2 (phase2_handle_t
*iph2
)
1013 if (iph2
->phase2_type
!= PHASE2_TYPE_SA
)
1015 if (FSM_STATE_IS_EXPIRED(iph2
->status
)) {
1019 SCHED_KILL(iph2
->sce
);
1022 "about to cleanup ph2: status %d, seq %d dying %d\n",
1023 iph2
->status
, iph2
->seq
, iph2
->is_dying
);
1025 /* send delete information */
1026 if (FSM_STATE_IS_ESTABLISHED(iph2
->status
)) {
1027 isakmp_info_send_d2(iph2
);
1029 // delete outgoing SAs
1030 if (iph2
->approval
) {
1033 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1035 pfkey_send_delete(lcconf
->sock_pfkey
,
1036 ipsecdoi2pfkey_proto(pr
->proto_id
),
1038 iph2
->src
, iph2
->dst
, pr
->spi_p
/* pr->reqid_out */);
1045 ike_session_unlink_phase2(iph2
);
1049 ike_session_cleanup_ph2_stub (void *p
)
1052 ike_session_cleanup_ph2((phase2_handle_t
*)p
);
1056 ike_session_cleanup_other_established_ph2s (ike_session_t
*session
,
1057 phase2_handle_t
*new_iph2
)
1059 phase2_handle_t
*p
, *next
;
1061 if (!session
|| !new_iph2
|| session
!= new_iph2
->parent_session
|| new_iph2
->phase2_type
!= PHASE2_TYPE_SA
) {
1062 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1067 * if we are responder, then we should wait until the server sends a delete notification.
1069 if (session
->is_client
&& new_iph2
->side
== RESPONDER
) {
1073 LIST_FOREACH_SAFE(p
, &session
->ph2tree
, ph2ofsession_chain
, next
) {
1075 * TODO: currently, most recently established SA wins. Need to revisit to see if
1076 * alternative selections is better.
1078 if (p
!= new_iph2
&& p
->spid
== new_iph2
->spid
&& !p
->is_dying
) {
1083 plog(ASL_LEVEL_NOTICE
,
1084 "IPsec-SA needs to be deleted: %s\n",
1085 sadbsecas2str(p
->src
, p
->dst
,
1086 p
->satype
, p
->spid
, 0));
1088 if (p
->side
== INITIATOR
) {
1089 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1090 p
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, p
);
1092 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1093 p
->sce
= sched_new(5, ike_session_cleanup_ph2_stub
, p
);
1100 ike_session_stopped_by_controller (ike_session_t
*session
,
1104 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1107 if (session
->stop_timestamp
.tv_sec
||
1108 session
->stop_timestamp
.tv_usec
) {
1109 plog(ASL_LEVEL_NOTICE
, "already stopped %s.\n", __FUNCTION__
);
1112 session
->stopped_by_vpn_controller
= 1;
1113 gettimeofday(&session
->stop_timestamp
, NULL
);
1114 if (!session
->term_reason
) {
1115 session
->term_reason
= (__typeof__(session
->term_reason
))reason
;
1120 ike_sessions_stopped_by_controller (struct sockaddr_storage
*remote
,
1124 ike_session_t
*p
= NULL
;
1125 ike_session_t
*next_session
= NULL
;
1128 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1132 LIST_FOREACH_SAFE(p
, &ike_session_tree
, chain
, next_session
) {
1133 if ((withport
&& cmpsaddrstrict(&p
->session_id
.remote
, remote
) == 0) ||
1134 (!withport
&& cmpsaddrwop(&p
->session_id
.remote
, remote
) == 0)) {
1135 ike_session_stopped_by_controller(p
, reason
);
1141 ike_session_purge_ph1s_by_session (ike_session_t
*session
)
1143 phase1_handle_t
*iph1
;
1144 phase1_handle_t
*next_iph1
= NULL
;
1146 LIST_FOREACH_SAFE(iph1
, &session
->ph1tree
, ph1ofsession_chain
, next_iph1
) {
1147 plog(ASL_LEVEL_NOTICE
, "deleteallph1 of given session: got a ph1 handler...\n");
1149 vpncontrol_notify_ike_failed(VPNCTL_NTYPE_NO_PROPOSAL_CHOSEN
, FROM_REMOTE
,
1150 iph1_get_remote_v4_address(iph1
), 0, NULL
);
1152 ike_session_unlink_phase1(iph1
);
1157 ike_session_purge_ph2s_by_ph1 (phase1_handle_t
*iph1
)
1159 phase2_handle_t
*p
, *next
;
1161 if (!iph1
|| !iph1
->parent_session
) {
1162 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1166 LIST_FOREACH_SAFE(p
, &iph1
->parent_session
->ph2tree
, ph2ofsession_chain
, next
) {
1174 plog(ASL_LEVEL_NOTICE
,
1175 "IPsec-SA needs to be purged: %s\n",
1176 sadbsecas2str(p
->src
, p
->dst
,
1177 p
->satype
, p
->spid
, 0));
1179 ike_session_cleanup_ph2(p
);
1184 ike_session_update_ph2_ports (phase2_handle_t
*iph2
)
1186 struct sockaddr_storage
*local
;
1187 struct sockaddr_storage
*remote
;
1189 if (iph2
->parent_session
) {
1190 local
= &iph2
->parent_session
->session_id
.local
;
1191 remote
= &iph2
->parent_session
->session_id
.remote
;
1193 set_port(iph2
->src
, extract_port(local
));
1194 set_port(iph2
->dst
, extract_port(remote
));
1196 plog(ASL_LEVEL_NOTICE
, "invalid parent session in %s.\n", __FUNCTION__
);
1201 ike_session_get_sas_for_stats (ike_session_t
*session
,
1204 struct sastat
*stats
,
1205 u_int32_t max_stats
)
1208 phase2_handle_t
*iph2
;
1210 if (!session
|| !seq
|| !stats
|| !max_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1211 plog(ASL_LEVEL_ERR
, "invalid args in %s.\n", __FUNCTION__
);
1216 LIST_FOREACH(iph2
, &session
->ph2tree
, ph2ofsession_chain
) {
1217 if (iph2
->approval
) {
1220 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1221 if (pr
->ok
&& pr
->proto_id
== IPSECDOI_PROTO_IPSEC_ESP
) {
1225 if (dir
== IPSEC_DIR_INBOUND
) {
1226 stats
[found
].spi
= pr
->spi
;
1228 stats
[found
].spi
= pr
->spi_p
;
1230 if (++found
== max_stats
) {
1241 ike_session_update_traffic_idle_status (ike_session_t
*session
,
1243 struct sastat
*new_stats
,
1244 u_int32_t max_stats
)
1246 int i
, j
, found
= 0, idle
= 1;
1248 if (!session
|| !new_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1249 plog(ASL_LEVEL_ERR
, "invalid args in %s.\n", __FUNCTION__
);
1253 if (!session
->established
|| session
->stopped_by_vpn_controller
|| session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
) {
1254 plog(ASL_LEVEL_NOTICE
, "dropping update on invalid session in %s.\n", __FUNCTION__
);
1258 for (i
= 0; i
< max_stats
; i
++) {
1259 if (dir
== IPSEC_DIR_INBOUND
) {
1260 for (j
= 0; j
< session
->traffic_monitor
.num_in_last_poll
; j
++) {
1261 if (new_stats
[i
].spi
!= session
->traffic_monitor
.in_last_poll
[j
].spi
) {
1265 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.in_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1270 for (j
= 0; j
< session
->traffic_monitor
.num_out_last_poll
; j
++) {
1271 if (new_stats
[i
].spi
!= session
->traffic_monitor
.out_last_poll
[j
].spi
) {
1275 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.out_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1280 // new SA.... check for any activity
1282 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
) {
1283 plog(ASL_LEVEL_NOTICE
, "new SA: dir %d....\n", dir
);
1288 if (dir
== IPSEC_DIR_INBOUND
) {
1289 // overwrite old stats
1290 bzero(session
->traffic_monitor
.in_last_poll
, sizeof(session
->traffic_monitor
.in_last_poll
));
1291 bcopy(new_stats
, session
->traffic_monitor
.in_last_poll
, (max_stats
* sizeof(*new_stats
)));
1292 session
->traffic_monitor
.num_in_last_poll
= max_stats
;
1294 //plog(ASL_LEVEL_DEBUG, "peer sent data....\n");
1295 session
->peer_sent_data_sc_dpd
= 1;
1296 session
->peer_sent_data_sc_idle
= 1;
1299 // overwrite old stats
1300 bzero(session
->traffic_monitor
.out_last_poll
, sizeof(session
->traffic_monitor
.out_last_poll
));
1301 bcopy(new_stats
, session
->traffic_monitor
.out_last_poll
, (max_stats
* sizeof(*new_stats
)));
1302 session
->traffic_monitor
.num_out_last_poll
= max_stats
;
1304 //plog(ASL_LEVEL_DEBUG, "i sent data....\n");
1305 session
->i_sent_data_sc_dpd
= 1;
1306 session
->i_sent_data_sc_idle
= 1;
1310 session
->last_time_data_sc_detected
= time(NULL
);
1312 ike_session_monitor_idle(session
);
1316 ike_session_cleanup (ike_session_t
*session
,
1319 phase2_handle_t
*iph2
= NULL
;
1320 phase2_handle_t
*next_iph2
= NULL
;
1321 phase1_handle_t
*iph1
= NULL
;
1322 phase1_handle_t
*next_iph1
= NULL
;
1323 nw_nat64_prefix_t nat64_prefix
;
1328 memset(&nat64_prefix
, 0, sizeof(nat64_prefix
));
1329 session
->is_dying
= 1;
1330 ike_session_stopped_by_controller(session
, reason
);
1332 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
1333 // do ph2's first... we need the ph1s for notifications
1334 LIST_FOREACH_SAFE(iph2
, &session
->ph2tree
, ph2ofsession_chain
, next_iph2
) {
1335 if (FSM_STATE_IS_ESTABLISHED(iph2
->status
)) {
1336 isakmp_info_send_d2(iph2
);
1338 isakmp_ph2expire(iph2
); // iph2 will go down 1 second later.
1341 // do the ph1s last.
1342 LIST_FOREACH_SAFE(iph1
, &session
->ph1tree
, ph1ofsession_chain
, next_iph1
) {
1344 if (iph1
->nat64_prefix
.length
> 0) {
1345 memcpy(&nat64_prefix
, &iph1
->nat64_prefix
, sizeof(nat64_prefix
));
1348 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
)) {
1349 isakmp_info_send_d1(iph1
);
1351 isakmp_ph1expire(iph1
);
1354 // send ipsecManager a notification
1355 if (session
->is_cisco_ipsec
&& reason
&& reason
!= ike_session_stopped_by_vpn_disconnect
1356 && reason
!= ike_session_stopped_by_controller_comm_lost
) {
1357 u_int32_t address
= 0;
1358 if ((&session
->session_id
.remote
)->ss_family
== AF_INET
) {
1359 address
= ((struct sockaddr_in
*)&session
->session_id
.remote
)->sin_addr
.s_addr
;
1361 if (nat64_prefix
.length
> 0) {
1362 struct in_addr inaddr
;
1363 nw_nat64_extract_v4(&nat64_prefix
,
1364 &((struct sockaddr_in6
*)&session
->session_id
.remote
)->sin6_addr
,
1366 address
= inaddr
.s_addr
;
1370 if (reason
== ike_session_stopped_by_idle
) {
1371 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT
, FROM_LOCAL
, address
, 0, NULL
);
1373 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_INTERNAL_ERROR
, FROM_LOCAL
, address
, 0, NULL
);
1379 ike_session_has_negoing_ph1 (ike_session_t
*session
)
1384 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1388 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
1389 if (!p
->is_dying
&& FSM_STATE_IS_NEGOTIATING(p
->status
)) {
1398 ike_session_has_established_ph1 (ike_session_t
*session
)
1403 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1407 LIST_FOREACH(p
, &session
->ph1tree
, ph1ofsession_chain
) {
1408 if (!p
->is_dying
&& FSM_STATE_IS_ESTABLISHED(p
->status
)) {
1417 ike_session_has_negoing_ph2 (ike_session_t
*session
)
1422 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1426 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
1427 if (!p
->is_dying
&& FSM_STATE_IS_NEGOTIATING(p
->status
)) {
1436 ike_session_has_established_ph2 (ike_session_t
*session
)
1441 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1445 LIST_FOREACH(p
, &session
->ph2tree
, ph2ofsession_chain
) {
1446 if (!p
->is_dying
&& FSM_STATE_IS_ESTABLISHED(p
->status
)) {
1455 ike_session_cleanup_ph1s_by_ph2 (phase2_handle_t
*iph2
)
1457 phase1_handle_t
*iph1
= NULL
;
1458 phase1_handle_t
*next_iph1
= NULL
;
1460 if (!iph2
|| !iph2
->parent_session
) {
1461 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1465 // phase1 is no longer useful
1466 LIST_FOREACH_SAFE(iph1
, &iph2
->parent_session
->ph1tree
, ph1ofsession_chain
, next_iph1
) {
1467 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
)) {
1468 isakmp_info_send_d1(iph1
);
1470 isakmp_ph1expire(iph1
);
1475 ike_session_is_client_ph2_rekey (phase2_handle_t
*iph2
)
1477 if (iph2
->parent_session
&&
1478 iph2
->parent_session
->is_client
&&
1480 iph2
->parent_session
->is_cisco_ipsec
) {
1487 ike_session_is_client_ph1_rekey (phase1_handle_t
*iph1
)
1489 if (iph1
->parent_session
&&
1490 iph1
->parent_session
->is_client
&&
1492 iph1
->parent_session
->is_cisco_ipsec
) {
1499 ike_session_is_client_ph1 (phase1_handle_t
*iph1
)
1501 if (iph1
->parent_session
&&
1502 iph1
->parent_session
->is_client
) {
1509 ike_session_is_client_ph2 (phase2_handle_t
*iph2
)
1511 if (iph2
->parent_session
&&
1512 iph2
->parent_session
->is_client
) {
1519 ike_session_start_xauth_timer (phase1_handle_t
*iph1
)
1521 // if there are no more established ph2s, start a timer to teardown the session
1522 if (iph1
->parent_session
&&
1523 iph1
->parent_session
->is_client
&&
1524 iph1
->parent_session
->is_cisco_ipsec
&&
1525 !iph1
->parent_session
->sc_xauth
) {
1526 iph1
->parent_session
->sc_xauth
= sched_new(300 /* 5 mins */,
1527 ike_session_cleanup_xauth_timeout
,
1528 iph1
->parent_session
);
1533 ike_session_stop_xauth_timer (phase1_handle_t
*iph1
)
1535 if (iph1
->parent_session
) {
1536 SCHED_KILL(iph1
->parent_session
->sc_xauth
);
1541 ike_session_is_id_ipany (vchar_t
*ext_id
)
1544 u_int8_t type
; /* ID Type */
1545 u_int8_t proto_id
; /* Protocol ID */
1546 u_int16_t port
; /* Port */
1547 u_int32_t addr
; /* IPv4 address */
1551 /* ignore protocol and port */
1552 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1553 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1554 id_ptr
->addr
== 0) {
1556 } else if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR_SUBNET
&&
1557 id_ptr
->mask
== 0 &&
1558 id_ptr
->addr
== 0) {
1561 plog(ASL_LEVEL_DEBUG
, "not ipany_ids in %s: type %d, addr %x, mask %x.\n",
1562 __FUNCTION__
, id_ptr
->type
, id_ptr
->addr
, id_ptr
->mask
);
1567 ike_session_is_id_portany (vchar_t
*ext_id
)
1570 u_int8_t type
; /* ID Type */
1571 u_int8_t proto_id
; /* Protocol ID */
1572 u_int16_t port
; /* Port */
1573 u_int32_t addr
; /* IPv4 address */
1578 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1579 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1580 id_ptr
->port
== 0) {
1583 plog(ASL_LEVEL_DEBUG
, "not portany_ids in %s: type %d, port %x.\n",
1584 __FUNCTION__
, id_ptr
->type
, id_ptr
->port
);
1589 ike_session_set_id_portany (vchar_t
*ext_id
)
1592 u_int8_t type
; /* ID Type */
1593 u_int8_t proto_id
; /* Protocol ID */
1594 u_int16_t port
; /* Port */
1595 u_int32_t addr
; /* IPv4 address */
1600 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1601 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
) {
1608 ike_session_cmp_ph2_ids_ipany (vchar_t
*ext_id
,
1611 if (ike_session_is_id_ipany(ext_id
) &&
1612 ike_session_is_id_ipany(ext_id_p
)) {
1619 * ipsec rekeys for l2tp-over-ipsec fail particularly when client is behind nat because the client's configs and policies don't
1620 * match the server's view of the client's address and port.
1621 * servers behave differently when using this address-port info to generate ids during phase2 rekeys, so try to match the incoming id to
1622 * a variety of info saved in the older phase2.
1625 ike_session_cmp_ph2_ids (phase2_handle_t
*iph2
,
1626 phase2_handle_t
*older_ph2
)
1628 vchar_t
*portany_id
= NULL
;
1629 vchar_t
*portany_id_p
= NULL
;
1631 if (iph2
->id
&& older_ph2
->id
&&
1632 iph2
->id
->l
== older_ph2
->id
->l
&&
1633 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1634 iph2
->id_p
&& older_ph2
->id_p
&&
1635 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1636 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1639 if (iph2
->ext_nat_id
&& older_ph2
->ext_nat_id
&&
1640 iph2
->ext_nat_id
->l
== older_ph2
->ext_nat_id
->l
&&
1641 memcmp(iph2
->ext_nat_id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->ext_nat_id
->l
) == 0 &&
1642 iph2
->ext_nat_id_p
&& older_ph2
->ext_nat_id_p
&&
1643 iph2
->ext_nat_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1644 memcmp(iph2
->ext_nat_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->ext_nat_id_p
->l
) == 0) {
1647 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1648 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1649 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1650 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1651 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1652 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1655 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1656 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1657 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1658 iph2
->id_p
&& older_ph2
->id_p
&&
1659 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1660 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1663 if (iph2
->id
&& older_ph2
->id
&&
1664 iph2
->id
->l
== older_ph2
->id
->l
&&
1665 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1666 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1667 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1668 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1672 /* check if the external id has a wildcard port and compare ids accordingly */
1673 if ((older_ph2
->ext_nat_id
&& ike_session_is_id_portany(older_ph2
->ext_nat_id
)) ||
1674 (older_ph2
->ext_nat_id_p
&& ike_session_is_id_portany(older_ph2
->ext_nat_id_p
))) {
1675 // try ignoring ports in iph2->id and iph2->id
1676 if (iph2
->id
&& (portany_id
= vdup(iph2
->id
))) {
1677 ike_session_set_id_portany(portany_id
);
1679 if (iph2
->id_p
&& (portany_id_p
= vdup(iph2
->id_p
))) {
1680 ike_session_set_id_portany(portany_id_p
);
1682 if (portany_id
&& older_ph2
->ext_nat_id
&&
1683 portany_id
->l
== older_ph2
->ext_nat_id
->l
&&
1684 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1685 portany_id_p
&& older_ph2
->ext_nat_id_p
&&
1686 portany_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1687 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1692 vfree(portany_id_p
);
1696 if (portany_id
&& iph2
->id
&& older_ph2
->ext_nat_id
&&
1697 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1698 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1699 iph2
->id_p
&& older_ph2
->id_p
&&
1700 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1701 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1706 vfree(portany_id_p
);
1710 if (portany_id_p
&& iph2
->id
&& older_ph2
->id
&&
1711 iph2
->id
->l
== older_ph2
->id
->l
&&
1712 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1713 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1714 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1715 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1720 vfree(portany_id_p
);
1728 vfree(portany_id_p
);
1735 ike_session_get_sainfo_r (phase2_handle_t
*iph2
)
1737 if (iph2
->parent_session
&&
1738 iph2
->parent_session
->is_client
&&
1739 iph2
->id
&& iph2
->id_p
) {
1741 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1742 plog(ASL_LEVEL_DEBUG
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1744 LIST_FOREACH(p
, &iph2
->parent_session
->ph2tree
, ph2ofsession_chain
) {
1745 if (iph2
!= p
&& !p
->is_dying
&& FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p
->status
) && p
->sainfo
) {
1746 plog(ASL_LEVEL_DEBUG
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1748 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1749 plog(ASL_LEVEL_DEBUG
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1750 iph2
->sainfo
= p
->sainfo
;
1752 retain_sainfo(iph2
->sainfo
);
1754 iph2
->spid
= p
->spid
;
1756 plog(ASL_LEVEL_DEBUG
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1758 if (p
->ext_nat_id
) {
1759 if (iph2
->ext_nat_id
) {
1760 vfree(iph2
->ext_nat_id
);
1762 iph2
->ext_nat_id
= vdup(p
->ext_nat_id
);
1764 if (p
->ext_nat_id_p
) {
1765 if (iph2
->ext_nat_id_p
) {
1766 vfree(iph2
->ext_nat_id_p
);
1768 iph2
->ext_nat_id_p
= vdup(p
->ext_nat_id_p
);
1779 ike_session_get_proposal_r (phase2_handle_t
*iph2
)
1781 if (iph2
->parent_session
&&
1782 iph2
->parent_session
->is_client
&&
1783 iph2
->id
&& iph2
->id_p
) {
1785 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1786 plog(ASL_LEVEL_DEBUG
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1788 LIST_FOREACH(p
, &iph2
->parent_session
->ph2tree
, ph2ofsession_chain
) {
1789 if (iph2
!= p
&& !p
->is_dying
&& FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p
->status
) &&
1791 plog(ASL_LEVEL_DEBUG
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1793 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1794 plog(ASL_LEVEL_DEBUG
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1795 iph2
->proposal
= dupsaprop(p
->approval
, 1);
1797 iph2
->spid
= p
->spid
;
1799 plog(ASL_LEVEL_DEBUG
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1810 ike_session_update_natt_version (phase1_handle_t
*iph1
)
1812 if (iph1
->parent_session
) {
1813 if (iph1
->natt_options
) {
1814 iph1
->parent_session
->natt_version
= iph1
->natt_options
->version
;
1816 iph1
->parent_session
->natt_version
= 0;
1822 ike_session_get_natt_version (phase1_handle_t
*iph1
)
1824 if (iph1
->parent_session
) {
1825 return(iph1
->parent_session
->natt_version
);
1831 ike_session_drop_rekey (ike_session_t
*session
, ike_session_rekey_type_t rekey_type
)
1834 if (session
->is_btmm_ipsec
&&
1835 session
->last_time_data_sc_detected
&&
1836 session
->traffic_monitor
.interv_mon
&&
1837 session
->traffic_monitor
.interv_idle
) {
1838 // for btmm: drop ph1/ph2 rekey if session is idle
1839 time_t now
= time(NULL
);
1841 if ((now
- session
->last_time_data_sc_detected
) > (session
->traffic_monitor
.interv_mon
<< 1)) {
1842 plog(ASL_LEVEL_NOTICE
, "btmm session is idle: drop ph%drekey.\n",
1846 } else if (!session
->is_btmm_ipsec
) {
1847 if (rekey_type
== IKE_SESSION_REKEY_TYPE_PH1
&&
1848 !ike_session_has_negoing_ph2(session
) && !ike_session_has_established_ph2(session
)) {
1849 // for vpn: only drop ph1 if there are no more ph2s.
1850 plog(ASL_LEVEL_NOTICE
, "vpn session is idle: drop ph1 rekey.\n");
1859 * this is called after racooon receives a 'kIOMessageSystemHasPoweredOn'
1860 * a lot is done to make sure that we don't sweep a session that's already been asserted.
1861 * however, it'll be too bad if the assertion comes after the session has already been swept.
1864 ike_session_sweep_sleepwake (void)
1866 ike_session_t
*p
= NULL
;
1867 ike_session_t
*next_session
= NULL
;
1869 // flag session as dying if all ph1/ph2 are dead/dying
1870 LIST_FOREACH_SAFE(p
, &ike_session_tree
, chain
, next_session
) {
1872 plog(ASL_LEVEL_NOTICE
, "skipping sweep of dying session.\n");
1875 SCHED_KILL(p
->sc_xauth
);
1876 if (p
->is_asserted
) {
1877 // for asserted session, traffic monitors will be restared after phase2 becomes established.
1878 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1879 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1880 plog(ASL_LEVEL_NOTICE
, "skipping sweep of asserted session.\n");
1884 // cleanup any stopped sessions as they will go down
1885 if (p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
1886 plog(ASL_LEVEL_NOTICE
, "sweeping stopped session.\n");
1887 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1891 if (!ike_session_has_established_ph1(p
) && !ike_session_has_established_ph2(p
)) {
1892 plog(ASL_LEVEL_NOTICE
, "session died while sleeping.\n");
1893 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1896 if (p
->traffic_monitor
.sc_mon
) {
1898 if (sched_get_time(p
->traffic_monitor
.sc_mon
, &xtime
)) {
1899 if (xtime
<= swept_at
) {
1900 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1901 if (!p
->is_dying
&& p
->traffic_monitor
.interv_mon
) {
1902 p
->traffic_monitor
.sc_mon
= sched_new(p
->traffic_monitor
.interv_mon
,
1903 ike_session_traffic_cop
,
1909 if (p
->traffic_monitor
.sc_idle
) {
1911 if (sched_get_time(p
->traffic_monitor
.sc_idle
, &xtime
)) {
1912 if (xtime
<= swept_at
) {
1913 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1914 if (!p
->is_dying
&& p
->traffic_monitor
.interv_idle
) {
1915 p
->traffic_monitor
.sc_idle
= sched_new(p
->traffic_monitor
.interv_idle
,
1916 ike_session_cleanup_idle
,
1926 * this is called after racooon receives an assert command from the controller/pppd.
1927 * this is intended to make racoon prepare to rekey both SAs because a network event occurred.
1928 * in the event of a sleepwake, the assert could happen before or after 'ike_session_sweep_sleepwake'.
1931 ike_session_assert_session (ike_session_t
*session
)
1933 phase2_handle_t
*iph2
= NULL
;
1934 phase2_handle_t
*iph2_next
= NULL
;
1935 phase1_handle_t
*iph1
= NULL
;
1936 phase1_handle_t
*iph1_next
= NULL
;
1938 if (!session
|| session
->is_dying
) {
1939 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
1943 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase2s
1944 LIST_FOREACH_SAFE(iph2
, &session
->ph2tree
, ph2ofsession_chain
, iph2_next
) {
1945 if (!iph2
->is_dying
&& !FSM_STATE_IS_EXPIRED(iph2
->status
)) {
1946 SCHED_KILL(iph2
->sce
);
1949 // delete SAs (in the kernel)
1950 if (FSM_STATE_IS_ESTABLISHED(iph2
->status
) && iph2
->approval
) {
1953 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1956 plog(ASL_LEVEL_NOTICE
,
1957 "Assert: Phase 2 %s deleted\n",
1958 sadbsecas2str(iph2
->src
, iph2
->dst
, iph2
->satype
, iph2
->spid
, ipsecdoi2pfkey_mode(pr
->encmode
)));
1960 pfkey_send_delete(lcconf
->sock_pfkey
,
1961 ipsecdoi2pfkey_proto(pr
->proto_id
),
1962 ipsecdoi2pfkey_mode(pr
->encmode
),
1963 iph2
->src
, iph2
->dst
, pr
->spi_p
);
1968 fsm_set_state(&iph2
->status
, IKEV1_STATE_PHASE2_EXPIRED
); // we want to delete SAs without telling the PEER
1969 iph2
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, iph2
);
1973 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase1s
1974 LIST_FOREACH_SAFE(iph1
, &session
->ph1tree
, ph1ofsession_chain
, iph1_next
) {
1975 if (!iph1
->is_dying
&& !FSM_STATE_IS_EXPIRED(iph1
->status
)) {
1976 SCHED_KILL(iph1
->sce
);
1977 SCHED_KILL(iph1
->sce_rekey
);
1981 plog(ASL_LEVEL_NOTICE
,
1982 "Assert: Phase 1 %s deleted\n",
1983 isakmp_pindex(&iph1
->index
, 0));
1985 ike_session_unbind_all_ph2_from_ph1(iph1
);
1987 fsm_set_state(&iph1
->status
, IKEV1_STATE_PHASE1_EXPIRED
); // we want to delete SAs without telling the PEER
1988 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
1989 iph1
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, iph1
);
1992 session
->is_asserted
= 1;
1998 ike_session_assert (struct sockaddr_storage
*local
,
1999 struct sockaddr_storage
*remote
)
2001 ike_session_t
*sess
;
2003 if (!local
|| !remote
) {
2004 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
2008 if ((sess
= ike_session_get_session(local
, remote
, FALSE
, NULL
))) {
2009 return(ike_session_assert_session(sess
));
2015 ike_session_ph2_retransmits (phase2_handle_t
*iph2
)
2017 int num_retransmits
;
2019 if (!iph2
->is_dying
&&
2022 iph2
->ph1
->sce_rekey
&& !sched_is_dead(iph2
->ph1
->sce_rekey
) &&
2023 iph2
->side
== INITIATOR
&&
2024 iph2
->parent_session
&&
2025 !iph2
->parent_session
->is_cisco_ipsec
&& /* not for Cisco */
2026 iph2
->parent_session
->is_client
) {
2027 num_retransmits
= iph2
->ph1
->rmconf
->retry_counter
- iph2
->retry_counter
;
2028 if (num_retransmits
== 3) {
2030 * phase2 negotiation is stalling on retransmits, inspite of a valid ph1.
2031 * one of the following is possible:
2032 * - (0) severe packet loss.
2033 * - (1) the peer is dead.
2034 * - (2) the peer is out of sync hence dropping this phase2 rekey (and perhaps responding with insecure
2035 * invalid-cookie notifications... but those are untrusted and so we can't rekey phase1 off that)
2036 * (2.1) the peer rebooted (or process restarted) and is now alive.
2037 * (2.2) the peer has deleted phase1 without notifying us (or the notification got dropped somehow).
2038 * (2.3) the peer has a policy/bug stopping this phase2 rekey
2040 * in all these cases, one sure way to know is to trigger a phase1 rekey early.
2042 plog(ASL_LEVEL_NOTICE
, "Many Phase 2 retransmits: try Phase 1 rekey and this Phase 2 to quit earlier.\n");
2043 isakmp_ph1rekeyexpire(iph2
->ph1
, TRUE
);
2044 iph2
->retry_counter
= 0;
2050 ike_session_ph1_retransmits (phase1_handle_t
*iph1
)
2052 int num_retransmits
;
2054 if (!iph1
->is_dying
&&
2057 FSM_STATE_IS_NEGOTIATING(iph1
->status
) &&
2058 iph1
->side
== INITIATOR
&&
2059 iph1
->parent_session
&&
2060 iph1
->parent_session
->is_client
&&
2061 !ike_session_has_other_negoing_ph1(iph1
->parent_session
, iph1
)) {
2062 num_retransmits
= iph1
->rmconf
->retry_counter
- iph1
->retry_counter
;
2063 if (num_retransmits
== 3) {
2064 plog(ASL_LEVEL_NOTICE
, "Many Phase 1 retransmits: try quit earlier.\n");
2065 iph1
->retry_counter
= 0;
2071 ike_session_bindph12(phase1_handle_t
*iph1
, phase2_handle_t
*iph2
)
2074 plog(ASL_LEVEL_ERR
, "Phase 2 already bound %s.\n", __FUNCTION__
);
2077 LIST_INSERT_HEAD(&iph1
->bound_ph2tree
, iph2
, ph1bind_chain
);
2081 ike_session_unbindph12(phase2_handle_t
*iph2
)
2083 if (iph2
->ph1
!= NULL
) {
2085 LIST_REMOVE(iph2
, ph1bind_chain
);
2090 ike_session_rebindph12(phase1_handle_t
*new_ph1
, phase2_handle_t
*iph2
)
2096 // reconcile the ph1-to-ph2 binding
2097 ike_session_unbindph12(iph2
);
2098 ike_session_bindph12(new_ph1
, iph2
);
2099 // recalculate ivm since ph1 binding has changed
2100 if (iph2
->ivm
!= NULL
) {
2101 oakley_delivm(iph2
->ivm
);
2102 if (FSM_STATE_IS_ESTABLISHED(new_ph1
->status
)) {
2103 iph2
->ivm
= oakley_newiv2(new_ph1
, iph2
->msgid
);
2104 plog(ASL_LEVEL_NOTICE
, "Phase 1-2 binding changed... recalculated ivm.\n");
2112 ike_session_unbind_all_ph2_from_ph1 (phase1_handle_t
*iph1
)
2114 phase2_handle_t
*p
= NULL
;
2115 phase2_handle_t
*next
= NULL
;
2117 LIST_FOREACH_SAFE(p
, &iph1
->bound_ph2tree
, ph1bind_chain
, next
) {
2118 ike_session_unbindph12(p
);
2123 ike_session_rebind_all_ph12_to_new_ph1 (phase1_handle_t
*old_iph1
,
2124 phase1_handle_t
*new_iph1
)
2126 phase2_handle_t
*p
= NULL
;
2127 phase2_handle_t
*next
= NULL
;
2129 if (old_iph1
== new_iph1
|| !old_iph1
|| !new_iph1
) {
2130 plog(ASL_LEVEL_ERR
, "invalid parameters in %s.\n", __FUNCTION__
);
2134 if (old_iph1
->parent_session
!= new_iph1
->parent_session
) {
2135 plog(ASL_LEVEL_ERR
, "Invalid parent sessions in %s.\n", __FUNCTION__
);
2139 LIST_FOREACH_SAFE(p
, &old_iph1
->bound_ph2tree
, ph1bind_chain
, next
) {
2140 if (p
->parent_session
!= new_iph1
->parent_session
) {
2141 plog(ASL_LEVEL_ERR
, "Mismatched parent session in ph1bind replacement.\n");
2143 if (p
->ph1
== new_iph1
) {
2144 plog(ASL_LEVEL_ERR
, "Same Phase 2 in ph1bind replacement in %s.\n",__FUNCTION__
);
2146 ike_session_rebindph12(new_iph1
, p
);