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>
35 #include "isakmp_var.h"
37 #include "ike_session.h"
40 #include "nattraversal.h"
43 #include "ipsec_doi.h"
44 #include "ipsecSessionTracer.h"
45 #include "ipsecMessageTracer.h"
46 #include "isakmp_inf.h"
47 #include "localconf.h"
48 #include "remoteconf.h"
49 #include "vpn_control.h"
50 #include "vpn_control_var.h"
53 #include "power_mgmt.h"
55 #define GET_SAMPLE_PERIOD(s,m) do { \
65 const char *ike_session_stopped_by_vpn_disconnect
= "Stopped by VPN disconnect";
66 const char *ike_session_stopped_by_controller_comm_lost
= "Stopped by loss of controller communication";
67 const char *ike_session_stopped_by_flush
= "Stopped by Flush";
68 const char *ike_session_stopped_by_idle
= "Stopped by Idle";
69 const char *ike_session_stopped_by_xauth_timeout
= "Stopped by XAUTH timeout";
70 const char *ike_session_stopped_by_sleepwake
= "Stopped by Sleep-Wake";
71 const char *ike_session_stopped_by_assert
= "Stopped by Assert";
73 static LIST_HEAD(_ike_session_tree_
, ike_session
) ike_session_tree
= { NULL
};
75 static ike_session_t
*
76 new_ike_session (ike_session_id_t
*id
)
78 ike_session_t
*session
;
81 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
85 plog(LLV_DEBUG
, LOCATION
, NULL
, "new parent session.\n");
86 session
= racoon_calloc(1, sizeof(*session
));
88 bzero(session
, sizeof(*session
));
89 memcpy(&session
->session_id
, id
, sizeof(*id
));
90 LIST_INIT(&session
->ikev1_state
.ph1tree
);
91 LIST_INIT(&session
->ikev1_state
.ph2tree
);
92 LIST_INSERT_HEAD(&ike_session_tree
, session
, chain
);
93 session
->version
= IKE_VERSION_1
; // hard-coded for now
94 IPSECSESSIONTRACERSTART(session
);
100 free_ike_session (ike_session_t
*session
)
102 int is_failure
= TRUE
;
104 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
105 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
106 SCHED_KILL(session
->sc_xauth
);
107 if (session
->start_timestamp
.tv_sec
|| session
->start_timestamp
.tv_usec
) {
108 if (!(session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
)) {
109 gettimeofday(&session
->stop_timestamp
, NULL
);
111 if (session
->term_reason
!= ike_session_stopped_by_vpn_disconnect
||
112 session
->term_reason
!= ike_session_stopped_by_controller_comm_lost
||
113 session
->term_reason
!= ike_session_stopped_by_flush
||
114 session
->term_reason
!= ike_session_stopped_by_idle
) {
117 IPSECSESSIONTRACERSTOP(session
,
119 session
->term_reason
);
121 // do MessageTracer cleanup here
122 plog(LLV_DEBUG
, LOCATION
, NULL
,
123 "Freeing IKE-Session to %s.\n",
124 saddr2str((struct sockaddr
*)&session
->session_id
.remote
));
125 LIST_REMOVE(session
, chain
);
126 racoon_free(session
);
131 ike_session_get_established_or_negoing_ph1 (ike_session_t
*session
)
133 struct ph1handle
*p
, *iph1
= NULL
;
136 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
140 // look for the most mature ph1 under the session
141 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
142 if (!p
->is_dying
&& p
->status
>= PHASE1ST_START
&& p
->status
<= PHASE1ST_ESTABLISHED
) {
143 if (!iph1
|| p
->status
> iph1
->status
) {
145 } else if (iph1
&& p
->status
== iph1
->status
) {
146 // TODO: pick better one based on farthest rekey/expiry remaining
155 ike_session_get_established_ph1 (ike_session_t
*session
)
160 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
164 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
165 if (!p
->is_dying
&& p
->status
== PHASE1ST_ESTABLISHED
) {
174 ike_session_init (void)
176 LIST_INIT(&ike_session_tree
);
180 ike_session_get_rekey_lifetime (int local_spi_is_higher
, u_int expiry_lifetime
)
182 u_int rekey_lifetime
= expiry_lifetime
/ 10;
184 if (rekey_lifetime
) {
185 if (local_spi_is_higher
) {
186 return (rekey_lifetime
* 9);
188 return (rekey_lifetime
* 8);
191 if (local_spi_is_higher
) {
192 rekey_lifetime
= expiry_lifetime
- 1;
194 rekey_lifetime
= expiry_lifetime
- 2;
197 if (rekey_lifetime
< expiry_lifetime
) {
198 return (rekey_lifetime
);
203 // TODO: optimize this mess later
205 ike_session_get_session (struct sockaddr_storage
*local
,
206 struct sockaddr_storage
*remote
,
211 ike_session_id_t id_default
;
212 ike_session_id_t id_floated_default
;
213 ike_session_id_t id_wop
;
214 ike_session_t
*best_match
= NULL
;
215 u_int16_t remote_port
;
216 int is_isakmp_remote_port
;
218 if (!local
|| !remote
) {
219 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
223 remote_port
= extract_port(remote
);
224 if (remote_port
&& remote_port
!= PORT_ISAKMP
&& remote_port
!= PORT_ISAKMP_NATT
) {
225 is_isakmp_remote_port
= 0;
227 is_isakmp_remote_port
= 1;
230 /* 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 */
231 bzero(&id
, sizeof(id
));
232 bzero(&id_default
, sizeof(id_default
));
233 bzero(&id_floated_default
, sizeof(id_floated_default
));
234 bzero(&id_wop
, sizeof(id_wop
));
235 if (local
->ss_family
== AF_INET
) {
236 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in
));
237 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in
));
238 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in
));
239 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in
));
240 } else if (local
->ss_family
== AF_INET6
) {
241 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in6
));
242 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in6
));
243 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in6
));
244 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in6
));
246 set_port(&id_default
.local
, PORT_ISAKMP
);
247 set_port(&id_floated_default
.local
, PORT_ISAKMP_NATT
);
248 set_port(&id_wop
.local
, 0);
249 if (remote
->ss_family
== AF_INET
) {
250 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in
));
251 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in
));
252 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in
));
253 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in
));
254 } else if (remote
->ss_family
== AF_INET6
) {
255 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in6
));
256 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
257 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
258 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in6
));
260 set_port(&id_default
.remote
, PORT_ISAKMP
);
261 set_port(&id_floated_default
.remote
, PORT_ISAKMP_NATT
);
262 set_port(&id_wop
.remote
, 0);
264 plog(LLV_DEBUG
, LOCATION
, local
,
265 "start search for IKE-Session. target %s.\n",
266 saddr2str((struct sockaddr
*)remote
));
268 for (p
= LIST_FIRST(&ike_session_tree
); p
; p
= LIST_NEXT(p
, chain
)) {
269 plog(LLV_DEBUG
, LOCATION
, local
,
270 "still search for IKE-Session. this %s.\n",
271 saddr2str((struct sockaddr
*)&p
->session_id
.remote
));
273 // for now: ignore any stopped sessions as they will go down
274 if (p
->is_dying
|| p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
275 plog(LLV_DEBUG
, LOCATION
, local
,
276 "still searching. skipping... session to %s is already stopped, active ph1 %d ph2 %d.\n",
277 saddr2str((struct sockaddr
*)&p
->session_id
.remote
),
278 p
->ikev1_state
.active_ph1cnt
, p
->ikev1_state
.active_ph2cnt
);
282 if (memcmp(&p
->session_id
, &id
, sizeof(id
)) == 0) {
283 plog(LLV_DEBUG
, LOCATION
, local
,
284 "Pre-existing IKE-Session to %s. case 1.\n",
285 saddr2str((struct sockaddr
*)remote
));
287 } else if (is_isakmp_remote_port
&& memcmp(&p
->session_id
, &id_default
, sizeof(id_default
)) == 0) {
288 plog(LLV_DEBUG
, LOCATION
, local
,
289 "Pre-existing IKE-Session to %s. case 2.\n",
290 saddr2str((struct sockaddr
*)remote
));
292 } else if (is_isakmp_remote_port
&& p
->ports_floated
&& memcmp(&p
->session_id
, &id_floated_default
, sizeof(id_floated_default
)) == 0) {
293 plog(LLV_DEBUG
, LOCATION
, local
,
294 "Pre-existing IKE-Session to %s. case 3.\n",
295 saddr2str((struct sockaddr
*)remote
));
297 } else if (is_isakmp_remote_port
&& memcmp(&p
->session_id
, &id_wop
, sizeof(id_wop
)) == 0) {
302 plog(LLV_DEBUG
, LOCATION
, local
,
303 "Best-match IKE-Session to %s.\n",
304 saddr2str((struct sockaddr
*)&best_match
->session_id
.remote
));
307 if (alloc_if_absent
) {
308 plog(LLV_DEBUG
, LOCATION
, local
,
309 "New IKE-Session to %s.\n",
310 saddr2str((struct sockaddr
*)&id
.remote
));
311 return new_ike_session(&id
);
318 ike_session_init_traffic_cop_params (struct ph1handle
*iph1
)
322 (!iph1
->rmconf
->idle_timeout
&& !iph1
->rmconf
->dpd_interval
)) {
326 if (!iph1
->parent_session
->traffic_monitor
.interv_idle
) {
327 iph1
->parent_session
->traffic_monitor
.interv_idle
= iph1
->rmconf
->idle_timeout
;
329 if (!iph1
->parent_session
->traffic_monitor
.dir_idle
) {
330 iph1
->parent_session
->traffic_monitor
.dir_idle
= iph1
->rmconf
->idle_timeout_dir
;
333 if (!iph1
->parent_session
->traffic_monitor
.interv_mon
) {
334 int min_period
, max_period
, sample_period
= 0;
336 /* calculate the sampling interval... half the smaller interval */
337 if (iph1
->rmconf
->dpd_interval
&&
338 (iph1
->rmconf
->dpd_algo
== DPD_ALGO_INBOUND_DETECT
||
339 iph1
->rmconf
->dpd_algo
== DPD_ALGO_BLACKHOLE_DETECT
)) {
340 // when certain types of dpd are enabled
341 min_period
= MIN(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
342 max_period
= MAX(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
343 } else if (iph1
->rmconf
->idle_timeout
) {
344 min_period
= max_period
= iph1
->rmconf
->idle_timeout
;
346 // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic
350 GET_SAMPLE_PERIOD(sample_period
, min_period
);
352 GET_SAMPLE_PERIOD(sample_period
, max_period
);
354 iph1
->parent_session
->traffic_monitor
.interv_mon
= sample_period
;
359 ike_session_link_ph1_to_session (struct ph1handle
*iph1
)
361 ike_session_t
*session
;
364 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
368 session
= ike_session_get_session(iph1
->local
, iph1
->remote
, TRUE
);
370 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to get session in %s.\n", __FUNCTION__
);
375 if (iph1
->parent_session
) {
376 if (session
== iph1
->parent_session
) {
379 // undo previous session
380 if (ike_session_unlink_ph1_from_session(iph1
) == 0) {
381 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to unlink ph1 in %s.\n", __FUNCTION__
);
382 free_ike_session(session
);
386 gettimeofday(&session
->start_timestamp
, NULL
);
390 if (iph1
->started_by_api
) {
391 session
->is_cisco_ipsec
= 1;
392 session
->is_l2tpvpn_ipsec
= 0;
393 session
->is_btmm_ipsec
= 0;
395 iph1
->parent_session
= session
;
396 LIST_INSERT_HEAD(&session
->ikev1_state
.ph1tree
, iph1
, ph1ofsession_chain
);
397 session
->ikev1_state
.active_ph1cnt
++;
398 if ((!session
->ikev1_state
.ph1cnt
&&
399 iph1
->side
== INITIATOR
) ||
400 iph1
->started_by_api
) {
401 // client initiates the first phase1 or, is started by controller api
402 session
->is_client
= 1;
404 if (session
->established
&&
405 session
->ikev1_state
.ph1cnt
) {
408 session
->ikev1_state
.ph1cnt
++;
409 ike_session_init_traffic_cop_params(iph1
);
415 ike_session_update_mode (struct ph2handle
*iph2
)
417 if (!iph2
|| !iph2
->parent_session
) {
421 // exit early if we already detected cisco-ipsec
422 if (iph2
->parent_session
->is_cisco_ipsec
) {
426 if (iph2
->approval
) {
427 if (!ipsecdoi_any_transportmode(iph2
->approval
)) {
428 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
429 iph2
->parent_session
->is_cisco_ipsec
= 0;
430 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
431 iph2
->parent_session
->is_btmm_ipsec
= 1;
433 } else if (ipsecdoi_transportmode(iph2
->approval
)) {
434 iph2
->parent_session
->is_cisco_ipsec
= 0;
435 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
436 iph2
->parent_session
->is_btmm_ipsec
= 0;
439 } else if (iph2
->proposal
) {
440 if (!ipsecdoi_any_transportmode(iph2
->proposal
)) {
441 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
442 iph2
->parent_session
->is_cisco_ipsec
= 0;
443 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
444 iph2
->parent_session
->is_btmm_ipsec
= 1;
446 } else if (ipsecdoi_transportmode(iph2
->proposal
)) {
447 iph2
->parent_session
->is_cisco_ipsec
= 0;
448 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
449 iph2
->parent_session
->is_btmm_ipsec
= 0;
456 ike_session_cleanup_xauth_timeout (void *arg
)
458 ike_session_t
*session
= (ike_session_t
*)arg
;
460 SCHED_KILL(session
->sc_xauth
);
461 // if there are no more established ph2s, start a timer to teardown the session
462 if (!ike_session_has_established_ph2(session
)) {
463 ike_session_cleanup(session
, ike_session_stopped_by_xauth_timeout
);
465 session
->sc_xauth
= sched_new(300 /* 5 mins */,
466 ike_session_cleanup_xauth_timeout
,
472 ike_session_link_ph2_to_session (struct ph2handle
*iph2
)
474 struct sockaddr_storage
*local
;
475 struct sockaddr_storage
*remote
;
476 ike_session_t
*session
;
479 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
486 session
= ike_session_get_session(local
, remote
, TRUE
);
488 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to get session in %s.\n", __FUNCTION__
);
493 if (iph2
->parent_session
) {
494 if (session
== iph2
->parent_session
) {
497 // undo previous session
498 if (ike_session_unlink_ph2_from_session(iph2
) == 0) {
499 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to unlink ph2 in %s.\n", __FUNCTION__
);
500 free_ike_session(session
);
505 iph2
->parent_session
= session
;
506 LIST_INSERT_HEAD(&session
->ikev1_state
.ph2tree
, iph2
, ph2ofsession_chain
);
507 session
->ikev1_state
.active_ph2cnt
++;
508 if (!session
->ikev1_state
.ph2cnt
&&
509 iph2
->side
== INITIATOR
) {
510 // client initiates the first phase2
511 session
->is_client
= 1;
513 if (session
->established
&&
514 session
->ikev1_state
.ph2cnt
) {
517 session
->ikev1_state
.ph2cnt
++;
519 ike_session_update_mode(iph2
);
525 ike_session_unlink_ph1_from_session (struct ph1handle
*iph1
)
527 ike_session_t
*session
;
529 if (!iph1
|| !iph1
->parent_session
) {
530 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
534 if (LIST_FIRST(&iph1
->ph2tree
)) {
535 // reparent any phase2 that may be hanging on to this phase1
536 ike_session_update_ph1_ph2tree(iph1
);
539 session
= iph1
->parent_session
;
540 LIST_REMOVE(iph1
, ph1ofsession_chain
);
541 iph1
->parent_session
= NULL
;
542 session
->ikev1_state
.active_ph1cnt
--;
543 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
544 session
->is_dying
= 1;
545 free_ike_session(session
);
552 ike_session_unlink_ph2_from_session (struct ph2handle
*iph2
)
554 ike_session_t
*session
;
556 if (!iph2
|| !iph2
->parent_session
) {
557 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
561 LIST_REMOVE(iph2
, ph2ofsession_chain
);
562 session
= iph2
->parent_session
;
563 iph2
->parent_session
= NULL
;
564 session
->ikev1_state
.active_ph2cnt
--;
565 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
566 session
->is_dying
= 1;
567 free_ike_session(session
);
574 ike_session_has_other_established_ph1 (ike_session_t
*session
, struct ph1handle
*iph1
)
582 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
583 if (iph1
!= p
&& !p
->is_dying
) {
584 if (p
->status
== PHASE1ST_ESTABLISHED
&& p
->sce_rekey
) {
594 ike_session_has_other_negoing_ph1 (ike_session_t
*session
, struct ph1handle
*iph1
)
599 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
603 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
604 if (iph1
!= p
&& !p
->is_dying
) {
605 if (p
->status
>= PHASE1ST_START
&& p
->status
<= PHASE1ST_ESTABLISHED
) {
615 ike_session_has_other_established_ph2 (ike_session_t
*session
, struct ph2handle
*iph2
)
620 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
624 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
625 if (iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
626 if (p
->status
== PHASE2ST_ESTABLISHED
) {
636 ike_session_has_other_negoing_ph2 (ike_session_t
*session
, struct ph2handle
*iph2
)
641 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
645 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
646 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: ph2 sub spid %d, db spid %d\n", __FUNCTION__
, iph2
->spid
, p
->spid
);
647 if (iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
648 if (p
->status
>= PHASE2ST_START
&& p
->status
<= PHASE2ST_ESTABLISHED
) {
658 ike_session_unbindph12_from_ph1 (struct ph1handle
*iph1
)
660 struct ph2handle
*p
, *next
;
662 for (p
= LIST_FIRST(&iph1
->ph2tree
); p
; p
= next
) {
663 // take next pointer now, since unbind and rebind may change the underlying ph2tree list
664 next
= LIST_NEXT(p
, ph1bind
);
670 ike_session_rebindph12_from_old_ph1_to_new_ph1 (struct ph1handle
*old_iph1
,
671 struct ph1handle
*new_iph1
)
673 struct ph2handle
*p
, *next
;
675 if (old_iph1
== new_iph1
|| !old_iph1
|| !new_iph1
) {
676 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
680 if (old_iph1
->parent_session
!= new_iph1
->parent_session
) {
681 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent sessions in %s.\n", __FUNCTION__
);
685 for (p
= LIST_FIRST(&old_iph1
->ph2tree
); p
; p
= next
) {
686 // take next pointer now, since rebind may change the underlying ph2tree list
687 next
= LIST_NEXT(p
, ph1bind
);
688 if (p
->parent_session
!= new_iph1
->parent_session
) {
689 plog(LLV_ERROR
, LOCATION
, NULL
, "mismatched parent session in ph1bind replacement.\n");
691 if (p
->ph1
== new_iph1
) {
692 plog(LLV_ERROR
, LOCATION
, NULL
, "same phase1 in ph1bind replacement in %s.\n",__FUNCTION__
);
694 rebindph12(new_iph1
, p
);
699 ike_session_verify_ph2_parent_session (struct ph2handle
*iph2
)
702 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
706 if (!iph2
->parent_session
) {
707 plog(LLV_DEBUG
, LOCATION
, NULL
, "NULL parent session.\n");
708 if (ike_session_link_ph2_to_session(iph2
)) {
709 plog(LLV_DEBUG
, LOCATION
, NULL
, "NULL parent session... still failed to link to session.\n");
710 // failed to bind ph2 to session
718 ike_session_update_ph1_ph2tree (struct ph1handle
*iph1
)
720 struct ph1handle
*new_iph1
= NULL
;
723 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
727 if (iph1
->parent_session
) {
728 new_iph1
= ike_session_get_established_ph1(iph1
->parent_session
);
731 plog(LLV_DEBUG2
, LOCATION
, NULL
, "no ph1bind replacement found. NULL ph1.\n");
732 ike_session_unbindph12_from_ph1(iph1
);
733 } else if (iph1
== new_iph1
) {
734 plog(LLV_DEBUG2
, LOCATION
, NULL
, "no ph1bind replacement found. same ph1.\n");
735 ike_session_unbindph12_from_ph1(iph1
);
737 ike_session_rebindph12_from_old_ph1_to_new_ph1(iph1
, new_iph1
);
740 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent session in %s.\n", __FUNCTION__
);
746 ike_session_update_ph2_ph1bind (struct ph2handle
*iph2
)
748 struct ph1handle
*iph1
;
751 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
755 iph1
= ike_session_get_established_ph1(iph2
->parent_session
);
756 if (iph1
&& iph2
->ph1
&& iph1
!= iph2
->ph1
) {
757 rebindph12(iph1
, iph2
);
758 } else if (iph1
&& !iph2
->ph1
) {
759 bindph12(iph1
, iph2
);
766 ike_session_ikev1_float_ports (struct ph1handle
*iph1
)
768 struct sockaddr_storage
*local
, *remote
;
771 if (iph1
->parent_session
) {
772 local
= &iph1
->parent_session
->session_id
.local
;
773 remote
= &iph1
->parent_session
->session_id
.remote
;
775 set_port(local
, extract_port(iph1
->local
));
776 set_port(remote
, extract_port(iph1
->remote
));
777 iph1
->parent_session
->ports_floated
= 1;
779 for (p
= LIST_FIRST(&iph1
->parent_session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
784 set_port(local
, extract_port(iph1
->local
));
785 set_port(remote
, extract_port(iph1
->remote
));
788 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent session in %s.\n", __FUNCTION__
);
793 ike_session_traffic_cop (void *arg
)
795 ike_session_t
*session
= (__typeof__(session
))arg
;
798 (session
->established
&& !session
->stopped_by_vpn_controller
&& !session
->stop_timestamp
.tv_sec
&& !session
->stop_timestamp
.tv_usec
)) {
799 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
800 /* get traffic query from kernel */
801 if (pk_sendget_inbound_sastats(session
) < 0) {
803 plog(LLV_DEBUG2
, LOCATION
, NULL
, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__
);
805 if (pk_sendget_outbound_sastats(session
) < 0) {
807 plog(LLV_DEBUG2
, LOCATION
, NULL
, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__
);
809 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
810 ike_session_traffic_cop
,
814 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
819 ike_session_cleanup_idle (void *arg
)
821 ike_session_cleanup((ike_session_t
*)arg
, ike_session_stopped_by_idle
);
825 ike_session_monitor_idle (ike_session_t
*session
)
830 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_INBOUND
||
831 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
832 if (session
->peer_sent_data_sc_idle
) {
833 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: restart idle-timeout because peer sent data. monitoring dir %d.\n",
834 __FUNCTION__
, session
->traffic_monitor
.dir_idle
);
835 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
836 if (session
->traffic_monitor
.interv_idle
) {
837 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
838 ike_session_cleanup_idle
,
841 session
->peer_sent_data_sc_idle
= 0;
842 session
->i_sent_data_sc_idle
= 0;
846 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_OUTBOUND
||
847 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
848 if (session
->i_sent_data_sc_idle
) {
849 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: restart idle-timeout because i sent data. monitoring dir %d.\n",
850 __FUNCTION__
, session
->traffic_monitor
.dir_idle
);
851 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
852 if (session
->traffic_monitor
.interv_idle
) {
853 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
854 ike_session_cleanup_idle
,
857 session
->peer_sent_data_sc_idle
= 0;
858 session
->i_sent_data_sc_idle
= 0;
865 ike_session_start_traffic_mon (ike_session_t
*session
)
867 if (session
->traffic_monitor
.interv_mon
) {
868 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
869 ike_session_traffic_cop
,
872 if (session
->traffic_monitor
.interv_idle
) {
873 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
874 ike_session_cleanup_idle
,
880 ike_session_ph2_established (struct ph2handle
*iph2
)
882 if (!iph2
->parent_session
) {
883 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
886 SCHED_KILL(iph2
->parent_session
->sc_xauth
);
887 if (!iph2
->parent_session
->established
) {
888 gettimeofday(&iph2
->parent_session
->estab_timestamp
, NULL
);
889 iph2
->parent_session
->established
= 1;
890 IPSECSESSIONTRACERESTABLISHED(iph2
->parent_session
);
891 ike_session_start_traffic_mon(iph2
->parent_session
);
892 } else if (iph2
->parent_session
->is_asserted
) {
893 ike_session_start_traffic_mon(iph2
->parent_session
);
895 iph2
->parent_session
->is_asserted
= 0;
896 // nothing happening to this session
897 iph2
->parent_session
->term_reason
= NULL
;
899 ike_session_update_mode(iph2
);
901 #ifdef ENABLE_VPNCONTROL_PORT
902 vpncontrol_notify_peer_resp_ph2(1, iph2
);
903 #endif /* ENABLE_VPNCONTROL_PORT */
904 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: ph2 established, spid %d\n", __FUNCTION__
, iph2
->spid
);
908 ike_session_cleanup_ph1 (struct ph1handle
*iph1
)
910 if (iph1
->status
== PHASE1ST_EXPIRED
) {
911 // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL
912 iph1
->sce
= sched_new(1, isakmp_ph1delete_stub
, iph1
);
916 /* send delete information */
917 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
918 isakmp_info_send_d1(iph1
);
921 isakmp_ph1expire(iph1
);
925 ike_session_cleanup_ph1_stub (void *p
)
928 ike_session_cleanup_ph1((struct ph1handle
*)p
);
932 ike_session_cleanup_other_established_ph1s (ike_session_t
*session
,
933 struct ph1handle
*new_iph1
)
935 struct ph1handle
*p
, *next
;
936 char *local
, *remote
;
938 if (!session
|| !new_iph1
|| session
!= new_iph1
->parent_session
) {
939 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
944 * if we are responder, then we should wait until the server sends a delete notification.
946 if (session
->is_client
&& new_iph1
->side
== RESPONDER
) {
950 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= next
) {
951 // take next pointer now, since delete change the underlying ph1tree list
952 next
= LIST_NEXT(p
, ph1ofsession_chain
);
954 * TODO: currently, most recently established SA wins. Need to revisit to see if
955 * alternative selections is better (e.g. largest p->index stays).
957 if (p
!= new_iph1
&& !p
->is_dying
) {
959 SCHED_KILL(p
->sce_rekey
);
963 local
= racoon_strdup(saddr2str((struct sockaddr
*)p
->local
));
964 remote
= racoon_strdup(saddr2str((struct sockaddr
*)p
->remote
));
966 STRDUP_FATAL(remote
);
967 plog(LLV_DEBUG
, LOCATION
, NULL
,
968 "ISAKMP-SA needs to be deleted %s-%s spi:%s\n",
969 local
, remote
, isakmp_pindex(&p
->index
, 0));
973 // first rebind the children ph2s of this dying ph1 to the new ph1.
974 ike_session_rebindph12_from_old_ph1_to_new_ph1 (p
, new_iph1
);
976 if (p
->side
== INITIATOR
) {
977 /* everyone deletes old outbound SA */
978 p
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, p
);
980 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
981 p
->sce
= sched_new(7, ike_session_cleanup_ph1_stub
, p
);
988 ike_session_cleanup_ph2 (struct ph2handle
*iph2
)
990 if (iph2
->status
== PHASE2ST_EXPIRED
) {
994 SCHED_KILL(iph2
->sce
);
996 plog(LLV_ERROR
, LOCATION
, NULL
,
997 "about to cleanup ph2: status %d, seq %d dying %d\n",
998 iph2
->status
, iph2
->seq
, iph2
->is_dying
);
1000 /* send delete information */
1001 if (iph2
->status
== PHASE2ST_ESTABLISHED
) {
1002 isakmp_info_send_d2(iph2
);
1004 // delete outgoing SAs
1005 if (iph2
->approval
) {
1008 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1010 pfkey_send_delete(lcconf
->sock_pfkey
,
1011 ipsecdoi2pfkey_proto(pr
->proto_id
),
1013 iph2
->src
, iph2
->dst
, pr
->spi_p
/* pr->reqid_out */);
1026 ike_session_cleanup_ph2_stub (void *p
)
1029 ike_session_cleanup_ph2((struct ph2handle
*)p
);
1033 ike_session_cleanup_other_established_ph2s (ike_session_t
*session
,
1034 struct ph2handle
*new_iph2
)
1036 struct ph2handle
*p
, *next
;
1038 if (!session
|| !new_iph2
|| session
!= new_iph2
->parent_session
) {
1039 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1044 * if we are responder, then we should wait until the server sends a delete notification.
1046 if (session
->is_client
&& new_iph2
->side
== RESPONDER
) {
1050 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= next
) {
1051 // take next pointer now, since delete change the underlying ph2tree list
1052 next
= LIST_NEXT(p
, ph2ofsession_chain
);
1054 * TODO: currently, most recently established SA wins. Need to revisit to see if
1055 * alternative selections is better.
1057 if (p
!= new_iph2
&& p
->spid
== new_iph2
->spid
&& !p
->is_dying
) {
1062 plog(LLV_DEBUG
, LOCATION
, NULL
,
1063 "IPsec-SA needs to be deleted: %s\n",
1064 sadbsecas2str(p
->src
, p
->dst
,
1065 p
->satype
, p
->spid
, 0));
1067 if (p
->side
== INITIATOR
) {
1068 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1069 p
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, p
);
1071 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1072 p
->sce
= sched_new(5, ike_session_cleanup_ph2_stub
, p
);
1079 ike_session_stopped_by_controller (ike_session_t
*session
,
1083 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1086 if (session
->stop_timestamp
.tv_sec
||
1087 session
->stop_timestamp
.tv_usec
) {
1088 plog(LLV_DEBUG2
, LOCATION
, NULL
, "already stopped %s.\n", __FUNCTION__
);
1091 session
->stopped_by_vpn_controller
= 1;
1092 gettimeofday(&session
->stop_timestamp
, NULL
);
1093 if (!session
->term_reason
) {
1094 session
->term_reason
= reason
;
1099 ike_sessions_stopped_by_controller (struct sockaddr_storage
*remote
,
1103 ike_session_t
*p
= NULL
;
1106 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1110 for (p
= LIST_FIRST(&ike_session_tree
); p
; p
= LIST_NEXT(p
, chain
)) {
1111 if (withport
&& cmpsaddrstrict(&p
->session_id
.remote
, remote
) == 0 ||
1112 !withport
&& cmpsaddrwop(&p
->session_id
.remote
, remote
) == 0) {
1113 ike_session_stopped_by_controller(p
, reason
);
1119 ike_session_purge_ph2s_by_ph1 (struct ph1handle
*iph1
)
1121 struct ph2handle
*p
, *next
;
1123 if (!iph1
|| !iph1
->parent_session
) {
1124 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1128 for (p
= LIST_FIRST(&iph1
->parent_session
->ikev1_state
.ph2tree
); p
; p
= next
) {
1129 // take next pointer now, since delete change the underlying ph2tree list
1130 next
= LIST_NEXT(p
, ph2ofsession_chain
);
1138 plog(LLV_DEBUG
, LOCATION
, NULL
,
1139 "IPsec-SA needs to be purged: %s\n",
1140 sadbsecas2str(p
->src
, p
->dst
,
1141 p
->satype
, p
->spid
, 0));
1143 ike_session_cleanup_ph2(p
);
1148 ike_session_update_ph2_ports (struct ph2handle
*iph2
)
1150 struct sockaddr_storage
*local
;
1151 struct sockaddr_storage
*remote
;
1153 if (iph2
->parent_session
) {
1154 local
= &iph2
->parent_session
->session_id
.local
;
1155 remote
= &iph2
->parent_session
->session_id
.remote
;
1157 set_port(iph2
->src
, extract_port(local
));
1158 set_port(iph2
->dst
, extract_port(remote
));
1160 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent session in %s.\n", __FUNCTION__
);
1165 ike_session_get_sas_for_stats (ike_session_t
*session
,
1168 struct sastat
*stats
,
1169 u_int32_t max_stats
)
1172 struct ph2handle
*iph2
;
1174 if (!session
|| !seq
|| !stats
|| !max_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1175 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid args in %s.\n", __FUNCTION__
);
1180 for (iph2
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); iph2
; iph2
= LIST_NEXT(iph2
, ph2ofsession_chain
)) {
1182 if (iph2
->approval
) {
1185 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1186 if (pr
->ok
&& pr
->proto_id
== IPSECDOI_PROTO_IPSEC_ESP
) {
1190 if (dir
== IPSEC_DIR_INBOUND
) {
1191 stats
[found
].spi
= pr
->spi
;
1193 stats
[found
].spi
= pr
->spi_p
;
1195 if (++found
== max_stats
) {
1206 ike_session_update_traffic_idle_status (ike_session_t
*session
,
1208 struct sastat
*new_stats
,
1209 u_int32_t max_stats
)
1211 int i
, j
, found
= 0, idle
= 1;
1213 if (!session
|| !new_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1214 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid args in %s.\n", __FUNCTION__
);
1218 if (!session
->established
|| session
->stopped_by_vpn_controller
|| session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
) {
1219 plog(LLV_DEBUG2
, LOCATION
, NULL
, "dropping update on invalid session in %s.\n", __FUNCTION__
);
1223 for (i
= 0; i
< max_stats
; i
++) {
1224 if (dir
== IPSEC_DIR_INBOUND
) {
1225 for (j
= 0; j
< session
->traffic_monitor
.num_in_last_poll
; j
++) {
1226 if (new_stats
[i
].spi
!= session
->traffic_monitor
.in_last_poll
[j
].spi
) {
1230 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.in_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1235 for (j
= 0; j
< session
->traffic_monitor
.num_out_last_poll
; j
++) {
1236 if (new_stats
[i
].spi
!= session
->traffic_monitor
.out_last_poll
[j
].spi
) {
1240 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.out_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1245 // new SA.... check for any activity
1247 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
) {
1248 plog(LLV_DEBUG
, LOCATION
, NULL
, "new SA: dir %d....\n", dir
);
1253 if (dir
== IPSEC_DIR_INBOUND
) {
1254 // overwrite old stats
1255 bzero(session
->traffic_monitor
.in_last_poll
, sizeof(session
->traffic_monitor
.in_last_poll
));
1256 bcopy(new_stats
, session
->traffic_monitor
.in_last_poll
, (max_stats
* sizeof(*new_stats
)));
1257 session
->traffic_monitor
.num_in_last_poll
= max_stats
;
1259 plog(LLV_DEBUG
, LOCATION
, NULL
, "peer sent data....\n");
1260 session
->peer_sent_data_sc_dpd
= 1;
1261 session
->peer_sent_data_sc_idle
= 1;
1264 // overwrite old stats
1265 bzero(session
->traffic_monitor
.out_last_poll
, sizeof(session
->traffic_monitor
.out_last_poll
));
1266 bcopy(new_stats
, session
->traffic_monitor
.out_last_poll
, (max_stats
* sizeof(*new_stats
)));
1267 session
->traffic_monitor
.num_out_last_poll
= max_stats
;
1269 plog(LLV_DEBUG
, LOCATION
, NULL
, "i sent data....\n");
1270 session
->i_sent_data_sc_dpd
= 1;
1271 session
->i_sent_data_sc_idle
= 1;
1275 session
->last_time_data_sc_detected
= time(NULL
);
1277 ike_session_monitor_idle(session
);
1281 ike_session_cleanup (ike_session_t
*session
,
1284 struct ph2handle
*iph2
;
1285 struct ph1handle
*iph1
;
1290 session
->is_dying
= 1;
1292 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
1293 // do ph2's first... we need the ph1s for notifications
1294 for (iph2
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); iph2
; iph2
= LIST_NEXT(iph2
, ph2ofsession_chain
)) {
1295 if (iph2
->status
== PHASE2ST_ESTABLISHED
) {
1296 isakmp_info_send_d2(iph2
);
1298 isakmp_ph2expire(iph2
); // iph2 will go down 1 second later.
1299 ike_session_stopped_by_controller(session
, reason
);
1302 // do the ph1s last.
1303 for (iph1
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); iph1
; iph1
= LIST_NEXT(iph1
, ph1ofsession_chain
)) {
1304 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
1305 isakmp_info_send_d1(iph1
);
1307 isakmp_ph1expire(iph1
);
1310 // send ipsecManager a notification
1311 if (session
->is_cisco_ipsec
&& reason
&& reason
!= ike_session_stopped_by_vpn_disconnect
1312 && reason
!= ike_session_stopped_by_controller_comm_lost
) {
1314 if ((&session
->session_id
.remote
)->ss_family
== AF_INET
) {
1315 address
= ((struct sockaddr_in
*)&session
->session_id
.remote
)->sin_addr
.s_addr
;
1320 if (reason
== ike_session_stopped_by_idle
) {
1321 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT
, FROM_LOCAL
, address
, 0, NULL
);
1323 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_INTERNAL_ERROR
, FROM_LOCAL
, address
, 0, NULL
);
1329 ike_session_has_negoing_ph1 (ike_session_t
*session
)
1331 struct ph1handle
*p
;
1334 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1338 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
1339 if (!p
->is_dying
&& p
->status
>= PHASE1ST_START
&& p
->status
<= PHASE1ST_ESTABLISHED
) {
1348 ike_session_has_established_ph1 (ike_session_t
*session
)
1350 struct ph1handle
*p
;
1353 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1357 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
1358 if (!p
->is_dying
&& p
->status
== PHASE1ST_ESTABLISHED
) {
1367 ike_session_has_negoing_ph2 (ike_session_t
*session
)
1369 struct ph2handle
*p
;
1372 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1376 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1377 if (!p
->is_dying
&& p
->status
>= PHASE2ST_START
&& p
->status
<= PHASE2ST_ESTABLISHED
) {
1386 ike_session_has_established_ph2 (ike_session_t
*session
)
1388 struct ph2handle
*p
;
1391 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1395 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1396 if (!p
->is_dying
&& p
->status
== PHASE2ST_ESTABLISHED
) {
1405 ike_session_cleanup_ph1s_by_ph2 (struct ph2handle
*iph2
)
1407 struct ph1handle
*iph1
;
1409 if (!iph2
|| !iph2
->parent_session
) {
1410 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1414 // phase1 is no longer useful
1415 for (iph1
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph1tree
); iph1
; iph1
= LIST_NEXT(iph1
, ph1ofsession_chain
)) {
1416 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
1417 isakmp_info_send_d1(iph1
);
1419 isakmp_ph1expire(iph1
);
1424 ike_session_is_client_ph2_rekey (struct ph2handle
*iph2
)
1426 if (iph2
->parent_session
&&
1427 iph2
->parent_session
->is_client
&&
1429 iph2
->parent_session
->is_cisco_ipsec
) {
1436 ike_session_is_client_ph1_rekey (struct ph1handle
*iph1
)
1438 if (iph1
->parent_session
&&
1439 iph1
->parent_session
->is_client
&&
1441 iph1
->parent_session
->is_cisco_ipsec
) {
1448 ike_session_start_xauth_timer (struct ph1handle
*iph1
)
1450 // if there are no more established ph2s, start a timer to teardown the session
1451 if (iph1
->parent_session
&&
1452 iph1
->parent_session
->is_client
&&
1453 iph1
->parent_session
->is_cisco_ipsec
&&
1454 !iph1
->parent_session
->sc_xauth
) {
1455 iph1
->parent_session
->sc_xauth
= sched_new(300 /* 5 mins */,
1456 ike_session_cleanup_xauth_timeout
,
1457 iph1
->parent_session
);
1462 ike_session_stop_xauth_timer (struct ph1handle
*iph1
)
1464 if (iph1
->parent_session
) {
1465 SCHED_KILL(iph1
->parent_session
->sc_xauth
);
1470 ike_session_is_id_ipany (vchar_t
*ext_id
)
1473 u_int8_t type
; /* ID Type */
1474 u_int8_t proto_id
; /* Protocol ID */
1475 u_int16_t port
; /* Port */
1476 u_int32_t addr
; /* IPv4 address */
1480 /* ignore protocol and port */
1481 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1482 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1483 id_ptr
->addr
== 0) {
1485 } else if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR_SUBNET
&&
1486 id_ptr
->mask
== 0 &&
1487 id_ptr
->addr
== 0) {
1490 plog(LLV_DEBUG2
, LOCATION
, NULL
, "not ipany_ids in %s: type %d, addr %x, mask %x.\n",
1491 __FUNCTION__
, id_ptr
->type
, id_ptr
->addr
, id_ptr
->mask
);
1496 ike_session_is_id_portany (vchar_t
*ext_id
)
1499 u_int8_t type
; /* ID Type */
1500 u_int8_t proto_id
; /* Protocol ID */
1501 u_int16_t port
; /* Port */
1502 u_int32_t addr
; /* IPv4 address */
1507 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1508 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1509 id_ptr
->port
== 0) {
1512 plog(LLV_DEBUG2
, LOCATION
, NULL
, "not portany_ids in %s: type %d, port %x.\n",
1513 __FUNCTION__
, id_ptr
->type
, id_ptr
->port
);
1518 ike_session_set_id_portany (vchar_t
*ext_id
)
1521 u_int8_t type
; /* ID Type */
1522 u_int8_t proto_id
; /* Protocol ID */
1523 u_int16_t port
; /* Port */
1524 u_int32_t addr
; /* IPv4 address */
1529 id_ptr
= ALIGNED_CAST(struct id
*)ext_id
->v
;
1530 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
) {
1537 ike_session_cmp_ph2_ids_ipany (vchar_t
*ext_id
,
1540 if (ike_session_is_id_ipany(ext_id
) &&
1541 ike_session_is_id_ipany(ext_id_p
)) {
1548 * ipsec rekeys for l2tp-over-ipsec fail particularly when client is behind nat because the client's configs and policies don't
1549 * match the server's view of the client's address and port.
1550 * servers behave differently when using this address-port info to generate ids during phase2 rekeys, so try to match the incoming id to
1551 * a variety of info saved in the older phase2.
1554 ike_session_cmp_ph2_ids (struct ph2handle
*iph2
,
1555 struct ph2handle
*older_ph2
)
1557 vchar_t
*portany_id
= NULL
;
1558 vchar_t
*portany_id_p
= NULL
;
1560 if (iph2
->id
&& older_ph2
->id
&&
1561 iph2
->id
->l
== older_ph2
->id
->l
&&
1562 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1563 iph2
->id_p
&& older_ph2
->id_p
&&
1564 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1565 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1568 if (iph2
->ext_nat_id
&& older_ph2
->ext_nat_id
&&
1569 iph2
->ext_nat_id
->l
== older_ph2
->ext_nat_id
->l
&&
1570 memcmp(iph2
->ext_nat_id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->ext_nat_id
->l
) == 0 &&
1571 iph2
->ext_nat_id_p
&& older_ph2
->ext_nat_id_p
&&
1572 iph2
->ext_nat_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1573 memcmp(iph2
->ext_nat_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->ext_nat_id_p
->l
) == 0) {
1576 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1577 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1578 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1579 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1580 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1581 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1584 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1585 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1586 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1587 iph2
->id_p
&& older_ph2
->id_p
&&
1588 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1589 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1592 if (iph2
->id
&& older_ph2
->id
&&
1593 iph2
->id
->l
== older_ph2
->id
->l
&&
1594 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1595 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1596 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1597 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1601 /* check if the external id has a wildcard port and compare ids accordingly */
1602 if ((older_ph2
->ext_nat_id
&& ike_session_is_id_portany(older_ph2
->ext_nat_id
)) ||
1603 (older_ph2
->ext_nat_id_p
&& ike_session_is_id_portany(older_ph2
->ext_nat_id_p
))) {
1604 // try ignoring ports in iph2->id and iph2->id
1605 if (iph2
->id
&& (portany_id
= vdup(iph2
->id
))) {
1606 ike_session_set_id_portany(portany_id
);
1608 if (iph2
->id_p
&& (portany_id_p
= vdup(iph2
->id_p
))) {
1609 ike_session_set_id_portany(portany_id_p
);
1611 if (portany_id
&& older_ph2
->ext_nat_id
&&
1612 portany_id
->l
== older_ph2
->ext_nat_id
->l
&&
1613 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1614 portany_id_p
&& older_ph2
->ext_nat_id_p
&&
1615 portany_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1616 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1621 vfree(portany_id_p
);
1625 if (portany_id
&& iph2
->id
&& older_ph2
->ext_nat_id
&&
1626 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1627 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_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) {
1635 vfree(portany_id_p
);
1639 if (portany_id_p
&& iph2
->id
&& older_ph2
->id
&&
1640 iph2
->id
->l
== older_ph2
->id
->l
&&
1641 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1642 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1643 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1644 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1649 vfree(portany_id_p
);
1657 vfree(portany_id_p
);
1664 ike_session_get_sainfo_r (struct ph2handle
*iph2
)
1666 if (iph2
->parent_session
&&
1667 iph2
->parent_session
->is_client
&&
1668 iph2
->id
&& iph2
->id_p
) {
1669 struct ph2handle
*p
;
1670 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1671 plog(LLV_DEBUG2
, LOCATION
, NULL
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1673 for (p
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1674 if (iph2
!= p
&& !p
->is_dying
&& p
->status
>= PHASE2ST_ESTABLISHED
&&
1675 p
->sainfo
&& !p
->sainfo
->to_delete
&& !p
->sainfo
->to_remove
) {
1676 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1678 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1679 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1680 iph2
->sainfo
= p
->sainfo
;
1682 if (link_sainfo_to_ph2(iph2
->sainfo
) != 0) {
1683 plog(LLV_ERROR
, LOCATION
, NULL
,
1684 "failed to link sainfo\n");
1685 iph2
->sainfo
= NULL
;
1690 iph2
->spid
= p
->spid
;
1692 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1694 if (p
->ext_nat_id
) {
1695 if (iph2
->ext_nat_id
) {
1696 vfree(iph2
->ext_nat_id
);
1698 iph2
->ext_nat_id
= vdup(p
->ext_nat_id
);
1700 if (p
->ext_nat_id_p
) {
1701 if (iph2
->ext_nat_id_p
) {
1702 vfree(iph2
->ext_nat_id_p
);
1704 iph2
->ext_nat_id_p
= vdup(p
->ext_nat_id_p
);
1715 ike_session_get_proposal_r (struct ph2handle
*iph2
)
1717 if (iph2
->parent_session
&&
1718 iph2
->parent_session
->is_client
&&
1719 iph2
->id
&& iph2
->id_p
) {
1720 struct ph2handle
*p
;
1721 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1722 plog(LLV_DEBUG2
, LOCATION
, NULL
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1724 for (p
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1725 if (iph2
!= p
&& !p
->is_dying
&& p
->status
>= PHASE2ST_ESTABLISHED
&&
1727 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1729 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1730 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1731 iph2
->proposal
= dupsaprop(p
->approval
, 1);
1733 iph2
->spid
= p
->spid
;
1735 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1746 ike_session_update_natt_version (struct ph1handle
*iph1
)
1748 if (iph1
->parent_session
) {
1749 if (iph1
->natt_options
) {
1750 iph1
->parent_session
->natt_version
= iph1
->natt_options
->version
;
1752 iph1
->parent_session
->natt_version
= 0;
1758 ike_session_get_natt_version (struct ph1handle
*iph1
)
1760 if (iph1
->parent_session
) {
1761 return(iph1
->parent_session
->natt_version
);
1767 ike_session_drop_rekey (ike_session_t
*session
, ike_session_rekey_type_t rekey_type
)
1770 if (session
->is_btmm_ipsec
&&
1771 session
->last_time_data_sc_detected
&&
1772 session
->traffic_monitor
.interv_mon
&&
1773 session
->traffic_monitor
.interv_idle
) {
1774 // for btmm: drop ph1/ph2 rekey if session is idle
1775 time_t now
= time(NULL
);
1777 if ((now
- session
->last_time_data_sc_detected
) > (session
->traffic_monitor
.interv_mon
<< 1)) {
1778 plog(LLV_DEBUG2
, LOCATION
, NULL
, "btmm session is idle: drop ph%drekey.\n",
1782 } else if (!session
->is_btmm_ipsec
) {
1783 if (rekey_type
== IKE_SESSION_REKEY_TYPE_PH1
&&
1784 !ike_session_has_negoing_ph2(session
)) {
1785 // for vpn: only drop ph1 if there are no more ph2s.
1786 plog(LLV_DEBUG2
, LOCATION
, NULL
, "vpn session is idle: drop ph1 rekey.\n");
1795 * this is called after racooon receives a 'kIOMessageSystemHasPoweredOn'
1796 * a lot is done to make sure that we don't sweep a session that's already been asserted.
1797 * however, it'll be too bad if the assertion comes after the session has already been swept.
1800 ike_session_sweep_sleepwake (void)
1804 // flag session as dying if all ph1/ph2 are dead/dying
1805 for (p
= LIST_FIRST(&ike_session_tree
); p
; p
= LIST_NEXT(p
, chain
)) {
1807 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of dying session.\n");
1810 SCHED_KILL(p
->sc_xauth
);
1811 if (p
->is_asserted
) {
1812 // for asserted session, traffic monitors will be restared after phase2 becomes established.
1813 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1814 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1815 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of asserted session.\n");
1819 // cleanup any stopped sessions as they will go down
1820 if (p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
1821 plog(LLV_DEBUG2
, LOCATION
, NULL
, "sweeping stopped session.\n");
1822 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1826 if (!ike_session_has_established_ph1(p
) && !ike_session_has_established_ph2(p
)) {
1827 plog(LLV_DEBUG2
, LOCATION
, NULL
, "session died while sleeping.\n");
1828 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1830 if (p
->traffic_monitor
.sc_mon
) {
1831 if (p
->traffic_monitor
.sc_mon
->xtime
<= swept_at
) {
1832 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1833 if (!p
->is_dying
&& p
->traffic_monitor
.interv_mon
) {
1834 p
->traffic_monitor
.sc_mon
= sched_new(p
->traffic_monitor
.interv_mon
,
1835 ike_session_traffic_cop
,
1840 if (p
->traffic_monitor
.sc_idle
) {
1841 if (p
->traffic_monitor
.sc_idle
->xtime
<= swept_at
) {
1842 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1843 if (!p
->is_dying
&& p
->traffic_monitor
.interv_idle
) {
1844 p
->traffic_monitor
.sc_idle
= sched_new(p
->traffic_monitor
.interv_idle
,
1845 ike_session_cleanup_idle
,
1854 * this is called after racooon receives an assert command from the controller/pppd.
1855 * this is intended to make racoon prepare to rekey both SAs because a network event occurred.
1856 * in the event of a sleepwake, the assert could happen before or after 'ike_session_sweep_sleepwake'.
1859 ike_session_assert_session (ike_session_t
*session
)
1861 struct ph2handle
*iph2
, *iph2_next
;
1862 struct ph1handle
*iph1
, *iph1_next
;
1864 if (!session
|| session
->is_dying
) {
1865 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1869 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase2s
1870 for (iph2
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); iph2
; iph2
= iph2_next
) {
1871 // take next pointer now, since delete change the underlying ph2tree list
1872 iph2_next
= LIST_NEXT(iph2
, ph2ofsession_chain
);
1873 if (!iph2
->is_dying
&& iph2
->status
< PHASE2ST_EXPIRED
) {
1874 SCHED_KILL(iph2
->sce
);
1877 // delete SAs (in the kernel)
1878 if (iph2
->status
== PHASE2ST_ESTABLISHED
&& iph2
->approval
) {
1881 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1884 plog(LLV_DEBUG
, LOCATION
, NULL
,
1885 "assert: phase2 %s deleted\n",
1886 sadbsecas2str(iph2
->src
, iph2
->dst
, iph2
->satype
, iph2
->spid
, ipsecdoi2pfkey_mode(pr
->encmode
)));
1888 pfkey_send_delete(lcconf
->sock_pfkey
,
1889 ipsecdoi2pfkey_proto(pr
->proto_id
),
1890 ipsecdoi2pfkey_mode(pr
->encmode
),
1891 iph2
->src
, iph2
->dst
, pr
->spi_p
);
1896 iph2
->status
= PHASE2ST_EXPIRED
; // we want to delete SAs without telling the PEER
1897 iph2
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, iph2
);
1901 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase1s
1902 for (iph1
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); iph1
; iph1
= iph1_next
) {
1903 // take next pointer now, since delete change the underlying ph1tree list
1904 iph1_next
= LIST_NEXT(iph1
, ph1ofsession_chain
);
1905 if (!iph1
->is_dying
&& iph1
->status
< PHASE1ST_EXPIRED
) {
1906 SCHED_KILL(iph1
->sce
);
1907 SCHED_KILL(iph1
->sce_rekey
);
1911 plog(LLV_DEBUG
, LOCATION
, NULL
,
1912 "assert: phase1 %s deleted\n",
1913 isakmp_pindex(&iph1
->index
, 0));
1915 ike_session_unbindph12_from_ph1(iph1
);
1917 iph1
->status
= PHASE1ST_EXPIRED
; // we want to delete SAs without telling the PEER
1918 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
1919 iph1
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, iph1
);
1922 session
->is_asserted
= 1;
1928 ike_session_assert (struct sockaddr_storage
*local
,
1929 struct sockaddr_storage
*remote
)
1931 ike_session_t
*sess
;
1933 if (!local
|| !remote
) {
1934 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1938 if ((sess
= ike_session_get_session(local
, remote
, FALSE
))) {
1939 return(ike_session_assert_session(sess
));
1945 ike_session_ph2_retransmits (struct ph2handle
*iph2
)
1947 int num_retransmits
;
1949 if (!iph2
->is_dying
&&
1952 iph2
->ph1
->sce_rekey
&& !iph2
->ph1
->sce_rekey
->dead
&&
1953 iph2
->side
== INITIATOR
&&
1954 iph2
->parent_session
&&
1955 !iph2
->parent_session
->is_cisco_ipsec
&& /* not for Cisco */
1956 iph2
->parent_session
->is_client
) {
1957 num_retransmits
= iph2
->ph1
->rmconf
->retry_counter
- iph2
->retry_counter
;
1958 if (num_retransmits
== 3) {
1960 * phase2 negotiation is stalling on retransmits, inspite of a valid ph1.
1961 * one of the following is possible:
1962 * - (0) severe packet loss.
1963 * - (1) the peer is dead.
1964 * - (2) the peer is out of sync hence dropping this phase2 rekey (and perhaps responding with insecure
1965 * invalid-cookie notifications... but those are untrusted and so we can't rekey phase1 off that)
1966 * (2.1) the peer rebooted (or process restarted) and is now alive.
1967 * (2.2) the peer has deleted phase1 without notifying us (or the notification got dropped somehow).
1968 * (2.3) the peer has a policy/bug stopping this phase2 rekey
1970 * in all these cases, one sure way to know is to trigger a phase1 rekey early.
1972 plog(LLV_DEBUG2
, LOCATION
, NULL
, "many phase2 retransmits: try phase1 rekey and this phase2 to quit earlier.\n");
1973 isakmp_ph1rekeyexpire(iph2
->ph1
, TRUE
);
1974 iph2
->retry_counter
= 0;
1980 ike_session_ph1_retransmits (struct ph1handle
*iph1
)
1982 int num_retransmits
;
1984 if (!iph1
->is_dying
&&
1987 iph1
->status
>= PHASE1ST_START
&& iph1
->status
< PHASE1ST_ESTABLISHED
&&
1988 iph1
->side
== INITIATOR
&&
1989 iph1
->parent_session
&&
1990 iph1
->parent_session
->is_client
&&
1991 !ike_session_has_other_negoing_ph1(iph1
->parent_session
, iph1
)) {
1992 num_retransmits
= iph1
->rmconf
->retry_counter
- iph1
->retry_counter
;
1993 if (num_retransmits
== 3) {
1994 plog(LLV_DEBUG2
, LOCATION
, NULL
, "many phase1 retransmits: try quit earlier.\n");
1995 iph1
->retry_counter
= 0;