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"
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_flush
= "Stopped by Flush";
66 const char *ike_session_stopped_by_idle
= "Stopped by Idle";
67 const char *ike_session_stopped_by_xauth_timeout
= "Stopped by XAUTH timeout";
68 const char *ike_session_stopped_by_sleepwake
= "Stopped by Sleep-Wake";
69 const char *ike_session_stopped_by_assert
= "Stopped by Assert";
71 static LIST_HEAD(_ike_session_tree_
, ike_session
) ike_session_tree
= { NULL
};
73 static ike_session_t
*
74 new_ike_session (ike_session_id_t
*id
)
76 ike_session_t
*session
;
79 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
83 plog(LLV_DEBUG
, LOCATION
, NULL
, "new parent session.\n");
84 session
= racoon_calloc(1, sizeof(*session
));
86 bzero(session
, sizeof(*session
));
87 memcpy(&session
->session_id
, id
, sizeof(*id
));
88 LIST_INIT(&session
->ikev1_state
.ph1tree
);
89 LIST_INIT(&session
->ikev1_state
.ph2tree
);
90 LIST_INSERT_HEAD(&ike_session_tree
, session
, chain
);
91 session
->version
= IKE_VERSION_1
; // hard-coded for now
92 IPSECSESSIONTRACERSTART(session
);
98 free_ike_session (ike_session_t
*session
)
100 int is_failure
= TRUE
;
102 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
103 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
104 SCHED_KILL(session
->sc_xauth
);
105 if (session
->start_timestamp
.tv_sec
|| session
->start_timestamp
.tv_usec
) {
106 if (!(session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
)) {
107 gettimeofday(&session
->stop_timestamp
, NULL
);
109 if (session
->term_reason
!= ike_session_stopped_by_vpn_disconnect
||
110 session
->term_reason
!= ike_session_stopped_by_flush
||
111 session
->term_reason
!= ike_session_stopped_by_idle
) {
114 IPSECSESSIONTRACERSTOP(session
,
116 session
->term_reason
);
118 // do MessageTracer cleanup here
119 plog(LLV_DEBUG
, LOCATION
, NULL
,
120 "Freeing IKE-Session to %s.\n",
121 saddr2str((struct sockaddr
*)&session
->session_id
.remote
));
122 LIST_REMOVE(session
, chain
);
123 racoon_free(session
);
128 ike_session_get_established_or_negoing_ph1 (ike_session_t
*session
)
130 struct ph1handle
*p
, *iph1
= NULL
;
133 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
137 // look for the most mature ph1 under the session
138 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
139 if (!p
->is_dying
&& p
->status
>= PHASE1ST_START
&& p
->status
<= PHASE1ST_ESTABLISHED
) {
140 if (!iph1
|| p
->status
> iph1
->status
) {
142 } else if (iph1
&& p
->status
== iph1
->status
) {
143 // TODO: pick better one based on farthest rekey/expiry remaining
152 ike_session_get_established_ph1 (ike_session_t
*session
)
157 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
161 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
162 if (!p
->is_dying
&& p
->status
== PHASE1ST_ESTABLISHED
) {
171 ike_session_init (void)
173 LIST_INIT(&ike_session_tree
);
177 ike_session_get_rekey_lifetime (int local_spi_is_higher
, u_int expiry_lifetime
)
179 u_int rekey_lifetime
= expiry_lifetime
/ 10;
181 if (rekey_lifetime
) {
182 if (local_spi_is_higher
) {
183 return (rekey_lifetime
* 9);
185 return (rekey_lifetime
* 8);
188 if (local_spi_is_higher
) {
189 rekey_lifetime
= expiry_lifetime
- 1;
191 rekey_lifetime
= expiry_lifetime
- 2;
194 if (rekey_lifetime
< expiry_lifetime
) {
195 return (rekey_lifetime
);
200 // TODO: optimize this mess later
202 ike_session_get_session (struct sockaddr
*local
,
203 struct sockaddr
*remote
,
208 ike_session_id_t id_default
;
209 ike_session_id_t id_floated_default
;
210 ike_session_id_t id_wop
;
211 ike_session_t
*best_match
= NULL
;
212 u_int16_t remote_port
;
213 int is_isakmp_remote_port
;
215 if (!local
|| !remote
) {
216 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
220 remote_port
= extract_port(remote
);
221 if (remote_port
&& remote_port
!= PORT_ISAKMP
&& remote_port
!= PORT_ISAKMP_NATT
) {
222 is_isakmp_remote_port
= 0;
224 is_isakmp_remote_port
= 1;
227 /* 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 */
228 bzero(&id
, sizeof(id
));
229 bzero(&id_default
, sizeof(id_default
));
230 bzero(&id_floated_default
, sizeof(id_floated_default
));
231 bzero(&id_wop
, sizeof(id_wop
));
232 if (local
->sa_family
== AF_INET
) {
233 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in
));
234 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in
));
235 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in
));
236 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in
));
237 } else if (local
->sa_family
== AF_INET6
) {
238 memcpy(&id
.local
, local
, sizeof(struct sockaddr_in6
));
239 memcpy(&id_default
.local
, local
, sizeof(struct sockaddr_in6
));
240 memcpy(&id_floated_default
.local
, local
, sizeof(struct sockaddr_in6
));
241 memcpy(&id_wop
.local
, local
, sizeof(struct sockaddr_in6
));
243 set_port((struct sockaddr
*)&id_default
.local
, PORT_ISAKMP
);
244 set_port((struct sockaddr
*)&id_floated_default
.local
, PORT_ISAKMP_NATT
);
245 set_port((struct sockaddr
*)&id_wop
.local
, 0);
246 if (remote
->sa_family
== AF_INET
) {
247 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in
));
248 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in
));
249 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in
));
250 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in
));
251 } else if (remote
->sa_family
== AF_INET6
) {
252 memcpy(&id
.remote
, remote
, sizeof(struct sockaddr_in6
));
253 memcpy(&id_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
254 memcpy(&id_floated_default
.remote
, remote
, sizeof(struct sockaddr_in6
));
255 memcpy(&id_wop
.remote
, remote
, sizeof(struct sockaddr_in6
));
257 set_port((struct sockaddr
*)&id_default
.remote
, PORT_ISAKMP
);
258 set_port((struct sockaddr
*)&id_floated_default
.remote
, PORT_ISAKMP_NATT
);
259 set_port((struct sockaddr
*)&id_wop
.remote
, 0);
261 plog(LLV_DEBUG
, LOCATION
, local
,
262 "start search for IKE-Session. target %s.\n",
265 for (p
= LIST_FIRST(&ike_session_tree
); p
; p
= LIST_NEXT(p
, chain
)) {
266 plog(LLV_DEBUG
, LOCATION
, local
,
267 "still search for IKE-Session. this %s.\n",
268 saddr2str((struct sockaddr
*)&p
->session_id
.remote
));
270 // for now: ignore any stopped sessions as they will go down
271 if (p
->is_dying
|| p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
272 plog(LLV_DEBUG
, LOCATION
, local
,
273 "still searching. skipping... session to %s is already stopped, active ph1 %d ph2 %d.\n",
274 saddr2str((struct sockaddr
*)&p
->session_id
.remote
),
275 p
->ikev1_state
.active_ph1cnt
, p
->ikev1_state
.active_ph2cnt
);
279 if (memcmp(&p
->session_id
, &id
, sizeof(id
)) == 0) {
280 plog(LLV_DEBUG
, LOCATION
, local
,
281 "Pre-existing IKE-Session to %s. case 1.\n",
284 } else if (is_isakmp_remote_port
&& memcmp(&p
->session_id
, &id_default
, sizeof(id_default
)) == 0) {
285 plog(LLV_DEBUG
, LOCATION
, local
,
286 "Pre-existing IKE-Session to %s. case 2.\n",
289 } else if (is_isakmp_remote_port
&& p
->ports_floated
&& memcmp(&p
->session_id
, &id_floated_default
, sizeof(id_floated_default
)) == 0) {
290 plog(LLV_DEBUG
, LOCATION
, local
,
291 "Pre-existing IKE-Session to %s. case 3.\n",
294 } else if (is_isakmp_remote_port
&& memcmp(&p
->session_id
, &id_wop
, sizeof(id_wop
)) == 0) {
299 plog(LLV_DEBUG
, LOCATION
, local
,
300 "Best-match IKE-Session to %s.\n",
301 saddr2str((struct sockaddr
*)&best_match
->session_id
.remote
));
304 if (alloc_if_absent
) {
305 plog(LLV_DEBUG
, LOCATION
, local
,
306 "New IKE-Session to %s.\n",
307 saddr2str((struct sockaddr
*)&id
.remote
));
308 return new_ike_session(&id
);
315 ike_session_init_traffic_cop_params (struct ph1handle
*iph1
)
319 (!iph1
->rmconf
->idle_timeout
&& !iph1
->rmconf
->dpd_interval
)) {
323 if (!iph1
->parent_session
->traffic_monitor
.interv_idle
) {
324 iph1
->parent_session
->traffic_monitor
.interv_idle
= iph1
->rmconf
->idle_timeout
;
326 if (!iph1
->parent_session
->traffic_monitor
.dir_idle
) {
327 iph1
->parent_session
->traffic_monitor
.dir_idle
= iph1
->rmconf
->idle_timeout_dir
;
330 if (!iph1
->parent_session
->traffic_monitor
.interv_mon
) {
331 int min_period
, max_period
, sample_period
= 0;
333 /* calculate the sampling interval... half the smaller interval */
334 if (iph1
->rmconf
->dpd_interval
&&
335 (iph1
->rmconf
->dpd_algo
== DPD_ALGO_INBOUND_DETECT
||
336 iph1
->rmconf
->dpd_algo
== DPD_ALGO_BLACKHOLE_DETECT
)) {
337 // when certain types of dpd are enabled
338 min_period
= MIN(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
339 max_period
= MAX(iph1
->rmconf
->dpd_interval
, iph1
->rmconf
->idle_timeout
);
340 } else if (iph1
->rmconf
->idle_timeout
) {
341 min_period
= max_period
= iph1
->rmconf
->idle_timeout
;
343 // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic
347 GET_SAMPLE_PERIOD(sample_period
, min_period
);
349 GET_SAMPLE_PERIOD(sample_period
, max_period
);
351 iph1
->parent_session
->traffic_monitor
.interv_mon
= sample_period
;
356 ike_session_link_ph1_to_session (struct ph1handle
*iph1
)
358 ike_session_t
*session
;
361 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
365 session
= ike_session_get_session(iph1
->local
, iph1
->remote
, TRUE
);
367 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to get session in %s.\n", __FUNCTION__
);
372 if (iph1
->parent_session
) {
373 if (session
== iph1
->parent_session
) {
376 // undo previous session
377 if (ike_session_unlink_ph1_from_session(iph1
) == 0) {
378 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to unlink ph1 in %s.\n", __FUNCTION__
);
379 free_ike_session(session
);
383 gettimeofday(&session
->start_timestamp
, NULL
);
387 if (iph1
->started_by_api
) {
388 session
->is_cisco_ipsec
= 1;
389 session
->is_l2tpvpn_ipsec
= 0;
390 session
->is_btmm_ipsec
= 0;
392 iph1
->parent_session
= session
;
393 LIST_INSERT_HEAD(&session
->ikev1_state
.ph1tree
, iph1
, ph1ofsession_chain
);
394 session
->ikev1_state
.active_ph1cnt
++;
395 if ((!session
->ikev1_state
.ph1cnt
&&
396 iph1
->side
== INITIATOR
) ||
397 iph1
->started_by_api
) {
398 // client initiates the first phase1 or, is started by controller api
399 session
->is_client
= 1;
401 if (session
->established
&&
402 session
->ikev1_state
.ph1cnt
) {
405 session
->ikev1_state
.ph1cnt
++;
406 ike_session_init_traffic_cop_params(iph1
);
412 ike_session_update_mode (struct ph2handle
*iph2
)
414 if (!iph2
|| !iph2
->parent_session
) {
418 // exit early if we already detected cisco-ipsec
419 if (iph2
->parent_session
->is_cisco_ipsec
) {
423 if (iph2
->approval
) {
424 if (!ipsecdoi_any_transportmode(iph2
->approval
)) {
425 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
426 iph2
->parent_session
->is_cisco_ipsec
= 0;
427 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
428 iph2
->parent_session
->is_btmm_ipsec
= 1;
430 } else if (ipsecdoi_transportmode(iph2
->approval
)) {
431 iph2
->parent_session
->is_cisco_ipsec
= 0;
432 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
433 iph2
->parent_session
->is_btmm_ipsec
= 0;
436 } else if (iph2
->proposal
) {
437 if (!ipsecdoi_any_transportmode(iph2
->proposal
)) {
438 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
439 iph2
->parent_session
->is_cisco_ipsec
= 0;
440 iph2
->parent_session
->is_l2tpvpn_ipsec
= 0;
441 iph2
->parent_session
->is_btmm_ipsec
= 1;
443 } else if (ipsecdoi_transportmode(iph2
->proposal
)) {
444 iph2
->parent_session
->is_cisco_ipsec
= 0;
445 iph2
->parent_session
->is_l2tpvpn_ipsec
= 1;
446 iph2
->parent_session
->is_btmm_ipsec
= 0;
453 ike_session_cleanup_xauth_timeout (void *arg
)
455 ike_session_t
*session
= (ike_session_t
*)arg
;
457 SCHED_KILL(session
->sc_xauth
);
458 // if there are no more established ph2s, start a timer to teardown the session
459 if (!ike_session_has_established_ph2(session
)) {
460 ike_session_cleanup(session
, ike_session_stopped_by_xauth_timeout
);
462 session
->sc_xauth
= sched_new(300 /* 5 mins */,
463 ike_session_cleanup_xauth_timeout
,
469 ike_session_link_ph2_to_session (struct ph2handle
*iph2
)
471 struct sockaddr
*local
;
472 struct sockaddr
*remote
;
473 ike_session_t
*session
;
476 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
483 session
= ike_session_get_session(local
, remote
, TRUE
);
485 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to get session in %s.\n", __FUNCTION__
);
490 if (iph2
->parent_session
) {
491 if (session
== iph2
->parent_session
) {
494 // undo previous session
495 if (ike_session_unlink_ph2_from_session(iph2
) == 0) {
496 plog(LLV_DEBUG2
, LOCATION
, NULL
, "failed to unlink ph2 in %s.\n", __FUNCTION__
);
497 free_ike_session(session
);
502 iph2
->parent_session
= session
;
503 LIST_INSERT_HEAD(&session
->ikev1_state
.ph2tree
, iph2
, ph2ofsession_chain
);
504 session
->ikev1_state
.active_ph2cnt
++;
505 if (!session
->ikev1_state
.ph2cnt
&&
506 iph2
->side
== INITIATOR
) {
507 // client initiates the first phase2
508 session
->is_client
= 1;
510 if (session
->established
&&
511 session
->ikev1_state
.ph2cnt
) {
514 session
->ikev1_state
.ph2cnt
++;
516 ike_session_update_mode(iph2
);
522 ike_session_unlink_ph1_from_session (struct ph1handle
*iph1
)
524 ike_session_t
*session
;
526 if (!iph1
|| !iph1
->parent_session
) {
527 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
531 if (LIST_FIRST(&iph1
->ph2tree
)) {
532 // reparent any phase2 that may be hanging on to this phase1
533 ike_session_update_ph1_ph2tree(iph1
);
536 session
= iph1
->parent_session
;
537 LIST_REMOVE(iph1
, ph1ofsession_chain
);
538 iph1
->parent_session
= NULL
;
539 session
->ikev1_state
.active_ph1cnt
--;
540 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
541 session
->is_dying
= 1;
542 free_ike_session(session
);
549 ike_session_unlink_ph2_from_session (struct ph2handle
*iph2
)
551 ike_session_t
*session
;
553 if (!iph2
|| !iph2
->parent_session
) {
554 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
558 LIST_REMOVE(iph2
, ph2ofsession_chain
);
559 session
= iph2
->parent_session
;
560 iph2
->parent_session
= NULL
;
561 session
->ikev1_state
.active_ph2cnt
--;
562 if (session
->ikev1_state
.active_ph1cnt
== 0 && session
->ikev1_state
.active_ph2cnt
== 0) {
563 session
->is_dying
= 1;
564 free_ike_session(session
);
571 ike_session_has_other_established_ph1 (ike_session_t
*session
, struct ph1handle
*iph1
)
579 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
580 if (iph1
!= p
&& !p
->is_dying
) {
581 if (p
->status
== PHASE1ST_ESTABLISHED
&& p
->sce_rekey
) {
591 ike_session_has_other_negoing_ph1 (ike_session_t
*session
, struct ph1handle
*iph1
)
596 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
600 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
601 if (iph1
!= p
&& !p
->is_dying
) {
602 if (p
->status
>= PHASE1ST_START
&& p
->status
<= PHASE1ST_ESTABLISHED
) {
612 ike_session_has_other_established_ph2 (ike_session_t
*session
, struct ph2handle
*iph2
)
617 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
621 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
622 if (iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
623 if (p
->status
== PHASE2ST_ESTABLISHED
) {
633 ike_session_has_other_negoing_ph2 (ike_session_t
*session
, struct ph2handle
*iph2
)
638 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
642 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
643 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: ph2 sub spid %d, db spid %d\n", __FUNCTION__
, iph2
->spid
, p
->spid
);
644 if (iph2
!= p
&& !p
->is_dying
&& iph2
->spid
== p
->spid
) {
645 if (p
->status
>= PHASE2ST_START
&& p
->status
<= PHASE2ST_ESTABLISHED
) {
655 ike_session_unbindph12_from_ph1 (struct ph1handle
*iph1
)
657 struct ph2handle
*p
, *next
;
659 for (p
= LIST_FIRST(&iph1
->ph2tree
); p
; p
= next
) {
660 // take next pointer now, since unbind and rebind may change the underlying ph2tree list
661 next
= LIST_NEXT(p
, ph1bind
);
667 ike_session_rebindph12_from_old_ph1_to_new_ph1 (struct ph1handle
*old_iph1
,
668 struct ph1handle
*new_iph1
)
670 struct ph2handle
*p
, *next
;
672 if (old_iph1
== new_iph1
|| !old_iph1
|| !new_iph1
) {
673 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
677 if (old_iph1
->parent_session
!= new_iph1
->parent_session
) {
678 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent sessions in %s.\n", __FUNCTION__
);
682 for (p
= LIST_FIRST(&old_iph1
->ph2tree
); p
; p
= next
) {
683 // take next pointer now, since rebind may change the underlying ph2tree list
684 next
= LIST_NEXT(p
, ph1bind
);
685 if (p
->parent_session
!= new_iph1
->parent_session
) {
686 plog(LLV_ERROR
, LOCATION
, NULL
, "mismatched parent session in ph1bind replacement.\n");
688 if (p
->ph1
== new_iph1
) {
689 plog(LLV_ERROR
, LOCATION
, NULL
, "same phase1 in ph1bind replacement in %s.\n",__FUNCTION__
);
691 rebindph12(new_iph1
, p
);
696 ike_session_verify_ph2_parent_session (struct ph2handle
*iph2
)
699 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
703 if (!iph2
->parent_session
) {
704 plog(LLV_DEBUG
, LOCATION
, NULL
, "NULL parent session.\n");
705 if (ike_session_link_ph2_to_session(iph2
)) {
706 plog(LLV_DEBUG
, LOCATION
, NULL
, "NULL parent session... still failed to link to session.\n");
707 // failed to bind ph2 to session
715 ike_session_update_ph1_ph2tree (struct ph1handle
*iph1
)
717 struct ph1handle
*new_iph1
= NULL
;
720 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
724 if (iph1
->parent_session
) {
725 new_iph1
= ike_session_get_established_ph1(iph1
->parent_session
);
728 plog(LLV_DEBUG2
, LOCATION
, NULL
, "no ph1bind replacement found. NULL ph1.\n");
729 ike_session_unbindph12_from_ph1(iph1
);
730 } else if (iph1
== new_iph1
) {
731 plog(LLV_DEBUG2
, LOCATION
, NULL
, "no ph1bind replacement found. same ph1.\n");
732 ike_session_unbindph12_from_ph1(iph1
);
734 ike_session_rebindph12_from_old_ph1_to_new_ph1(iph1
, new_iph1
);
737 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent session in %s.\n", __FUNCTION__
);
743 ike_session_update_ph2_ph1bind (struct ph2handle
*iph2
)
745 struct ph1handle
*iph1
;
748 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
752 iph1
= ike_session_get_established_ph1(iph2
->parent_session
);
753 if (iph1
&& iph2
->ph1
&& iph1
!= iph2
->ph1
) {
754 rebindph12(iph1
, iph2
);
755 } else if (iph1
&& !iph2
->ph1
) {
756 bindph12(iph1
, iph2
);
763 ike_session_ikev1_float_ports (struct ph1handle
*iph1
)
765 struct sockaddr
*local
, *remote
;
768 if (iph1
->parent_session
) {
769 local
= (struct sockaddr
*)&iph1
->parent_session
->session_id
.local
;
770 remote
= (struct sockaddr
*)&iph1
->parent_session
->session_id
.remote
;
772 set_port(local
, extract_port(iph1
->local
));
773 set_port(remote
, extract_port(iph1
->remote
));
774 iph1
->parent_session
->ports_floated
= 1;
776 for (p
= LIST_FIRST(&iph1
->parent_session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
781 set_port(local
, extract_port(iph1
->local
));
782 set_port(remote
, extract_port(iph1
->remote
));
785 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent session in %s.\n", __FUNCTION__
);
790 ike_session_traffic_cop (void *arg
)
792 ike_session_t
*session
= (__typeof__(session
))arg
;
795 (session
->established
&& !session
->stopped_by_vpn_controller
&& !session
->stop_timestamp
.tv_sec
&& !session
->stop_timestamp
.tv_usec
)) {
796 SCHED_KILL(session
->traffic_monitor
.sc_mon
);
797 /* get traffic query from kernel */
798 if (pk_sendget_inbound_sastats(session
) < 0) {
800 plog(LLV_DEBUG2
, LOCATION
, NULL
, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__
);
802 if (pk_sendget_outbound_sastats(session
) < 0) {
804 plog(LLV_DEBUG2
, LOCATION
, NULL
, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__
);
806 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
807 ike_session_traffic_cop
,
811 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
816 ike_session_cleanup_idle (void *arg
)
818 ike_session_cleanup((ike_session_t
*)arg
, ike_session_stopped_by_idle
);
822 ike_session_monitor_idle (ike_session_t
*session
)
827 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_INBOUND
||
828 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
829 if (session
->peer_sent_data_sc_idle
) {
830 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: restart idle-timeout because peer sent data. monitoring dir %d.\n",
831 __FUNCTION__
, session
->traffic_monitor
.dir_idle
);
832 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
833 if (session
->traffic_monitor
.interv_idle
) {
834 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
835 ike_session_cleanup_idle
,
838 session
->peer_sent_data_sc_idle
= 0;
839 session
->i_sent_data_sc_idle
= 0;
843 if (session
->traffic_monitor
.dir_idle
== IPSEC_DIR_OUTBOUND
||
844 session
->traffic_monitor
.dir_idle
== IPSEC_DIR_ANY
) {
845 if (session
->i_sent_data_sc_idle
) {
846 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: restart idle-timeout because i sent data. monitoring dir %d.\n",
847 __FUNCTION__
, session
->traffic_monitor
.dir_idle
);
848 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
849 if (session
->traffic_monitor
.interv_idle
) {
850 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
851 ike_session_cleanup_idle
,
854 session
->peer_sent_data_sc_idle
= 0;
855 session
->i_sent_data_sc_idle
= 0;
862 ike_session_start_traffic_mon (ike_session_t
*session
)
864 if (session
->traffic_monitor
.interv_mon
) {
865 session
->traffic_monitor
.sc_mon
= sched_new(session
->traffic_monitor
.interv_mon
,
866 ike_session_traffic_cop
,
869 if (session
->traffic_monitor
.interv_idle
) {
870 session
->traffic_monitor
.sc_idle
= sched_new(session
->traffic_monitor
.interv_idle
,
871 ike_session_cleanup_idle
,
877 ike_session_ph2_established (struct ph2handle
*iph2
)
879 if (!iph2
->parent_session
) {
880 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
883 SCHED_KILL(iph2
->parent_session
->sc_xauth
);
884 if (!iph2
->parent_session
->established
) {
885 gettimeofday(&iph2
->parent_session
->estab_timestamp
, NULL
);
886 iph2
->parent_session
->established
= 1;
887 IPSECSESSIONTRACERESTABLISHED(iph2
->parent_session
);
888 ike_session_start_traffic_mon(iph2
->parent_session
);
889 } else if (iph2
->parent_session
->is_asserted
) {
890 ike_session_start_traffic_mon(iph2
->parent_session
);
892 iph2
->parent_session
->is_asserted
= 0;
893 // nothing happening to this session
894 iph2
->parent_session
->term_reason
= NULL
;
896 ike_session_update_mode(iph2
);
898 #ifdef ENABLE_VPNCONTROL_PORT
899 vpncontrol_notify_peer_resp_ph2(1, iph2
);
900 #endif /* ENABLE_VPNCONTROL_PORT */
901 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: ph2 established, spid %d\n", __FUNCTION__
, iph2
->spid
);
905 ike_session_cleanup_ph1 (struct ph1handle
*iph1
)
907 if (iph1
->status
== PHASE1ST_EXPIRED
) {
908 // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL
909 iph1
->sce
= sched_new(1, isakmp_ph1delete_stub
, iph1
);
913 /* send delete information */
914 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
915 isakmp_info_send_d1(iph1
);
918 isakmp_ph1expire(iph1
);
922 ike_session_cleanup_ph1_stub (void *p
)
925 ike_session_cleanup_ph1((struct ph1handle
*)p
);
929 ike_session_cleanup_other_established_ph1s (ike_session_t
*session
,
930 struct ph1handle
*new_iph1
)
932 struct ph1handle
*p
, *next
;
933 char *local
, *remote
;
935 if (!session
|| !new_iph1
|| session
!= new_iph1
->parent_session
) {
936 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
941 * if we are responder, then we should wait until the server sends a delete notification.
943 if (session
->is_client
&& new_iph1
->side
== RESPONDER
) {
947 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= next
) {
948 // take next pointer now, since delete change the underlying ph1tree list
949 next
= LIST_NEXT(p
, ph1ofsession_chain
);
951 * TODO: currently, most recently established SA wins. Need to revisit to see if
952 * alternative selections is better (e.g. largest p->index stays).
954 if (p
!= new_iph1
&& !p
->is_dying
) {
956 SCHED_KILL(p
->sce_rekey
);
960 local
= racoon_strdup(saddr2str(p
->local
));
961 remote
= racoon_strdup(saddr2str(p
->remote
));
963 STRDUP_FATAL(remote
);
964 plog(LLV_DEBUG
, LOCATION
, NULL
,
965 "ISAKMP-SA needs to be deleted %s-%s spi:%s\n",
966 local
, remote
, isakmp_pindex(&p
->index
, 0));
970 // first rebind the children ph2s of this dying ph1 to the new ph1.
971 ike_session_rebindph12_from_old_ph1_to_new_ph1 (p
, new_iph1
);
973 if (p
->side
== INITIATOR
) {
974 /* everyone deletes old outbound SA */
975 p
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, p
);
977 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
978 p
->sce
= sched_new(7, ike_session_cleanup_ph1_stub
, p
);
985 ike_session_cleanup_ph2 (struct ph2handle
*iph2
)
987 if (iph2
->status
== PHASE2ST_EXPIRED
) {
991 SCHED_KILL(iph2
->sce
);
993 plog(LLV_ERROR
, LOCATION
, NULL
,
994 "about to cleanup ph2: status %d, seq %d dying %d\n",
995 iph2
->status
, iph2
->seq
, iph2
->is_dying
);
997 /* send delete information */
998 if (iph2
->status
== PHASE2ST_ESTABLISHED
) {
999 isakmp_info_send_d2(iph2
);
1001 // delete outgoing SAs
1002 if (iph2
->approval
) {
1005 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1007 pfkey_send_delete(lcconf
->sock_pfkey
,
1008 ipsecdoi2pfkey_proto(pr
->proto_id
),
1010 iph2
->src
, iph2
->dst
, pr
->spi_p
/* pr->reqid_out */);
1023 ike_session_cleanup_ph2_stub (void *p
)
1026 ike_session_cleanup_ph2((struct ph2handle
*)p
);
1030 ike_session_cleanup_other_established_ph2s (ike_session_t
*session
,
1031 struct ph2handle
*new_iph2
)
1033 struct ph2handle
*p
, *next
;
1035 if (!session
|| !new_iph2
|| session
!= new_iph2
->parent_session
) {
1036 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1041 * if we are responder, then we should wait until the server sends a delete notification.
1043 if (session
->is_client
&& new_iph2
->side
== RESPONDER
) {
1047 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= next
) {
1048 // take next pointer now, since delete change the underlying ph2tree list
1049 next
= LIST_NEXT(p
, ph2ofsession_chain
);
1051 * TODO: currently, most recently established SA wins. Need to revisit to see if
1052 * alternative selections is better.
1054 if (p
!= new_iph2
&& p
->spid
== new_iph2
->spid
&& !p
->is_dying
) {
1059 plog(LLV_DEBUG
, LOCATION
, NULL
,
1060 "IPsec-SA needs to be deleted: %s\n",
1061 sadbsecas2str(p
->src
, p
->dst
,
1062 p
->satype
, p
->spid
, 0));
1064 if (p
->side
== INITIATOR
) {
1065 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1066 p
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, p
);
1068 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
1069 p
->sce
= sched_new(5, ike_session_cleanup_ph2_stub
, p
);
1076 ike_session_stopped_by_controller (ike_session_t
*session
,
1080 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1083 if (session
->stop_timestamp
.tv_sec
||
1084 session
->stop_timestamp
.tv_usec
) {
1085 plog(LLV_DEBUG2
, LOCATION
, NULL
, "already stopped %s.\n", __FUNCTION__
);
1088 session
->stopped_by_vpn_controller
= 1;
1089 gettimeofday(&session
->stop_timestamp
, NULL
);
1090 if (!session
->term_reason
) {
1091 session
->term_reason
= reason
;
1096 ike_sessions_stopped_by_controller (struct sockaddr
*remote
,
1100 ike_session_t
*p
= NULL
;
1103 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1107 for (p
= LIST_FIRST(&ike_session_tree
); p
; p
= LIST_NEXT(p
, chain
)) {
1108 if (withport
&& cmpsaddrstrict(&p
->session_id
.remote
, remote
) == 0 ||
1109 !withport
&& cmpsaddrwop(&p
->session_id
.remote
, remote
) == 0) {
1110 ike_session_stopped_by_controller(p
, reason
);
1116 ike_session_purge_ph2s_by_ph1 (struct ph1handle
*iph1
)
1118 struct ph2handle
*p
, *next
;
1120 if (!iph1
|| !iph1
->parent_session
) {
1121 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1125 for (p
= LIST_FIRST(&iph1
->parent_session
->ikev1_state
.ph2tree
); p
; p
= next
) {
1126 // take next pointer now, since delete change the underlying ph2tree list
1127 next
= LIST_NEXT(p
, ph2ofsession_chain
);
1135 plog(LLV_DEBUG
, LOCATION
, NULL
,
1136 "IPsec-SA needs to be purged: %s\n",
1137 sadbsecas2str(p
->src
, p
->dst
,
1138 p
->satype
, p
->spid
, 0));
1140 ike_session_cleanup_ph2(p
);
1145 ike_session_update_ph2_ports (struct ph2handle
*iph2
)
1147 struct sockaddr
*local
;
1148 struct sockaddr
*remote
;
1150 if (iph2
->parent_session
) {
1151 local
= (struct sockaddr
*)&iph2
->parent_session
->session_id
.local
;
1152 remote
= (struct sockaddr
*)&iph2
->parent_session
->session_id
.remote
;
1154 set_port(iph2
->src
, extract_port(local
));
1155 set_port(iph2
->dst
, extract_port(remote
));
1157 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parent session in %s.\n", __FUNCTION__
);
1162 ike_session_get_sas_for_stats (ike_session_t
*session
,
1165 struct sastat
*stats
,
1166 u_int32_t max_stats
)
1169 struct ph2handle
*iph2
;
1171 if (!session
|| !seq
|| !stats
|| !max_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1172 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid args in %s.\n", __FUNCTION__
);
1177 for (iph2
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); iph2
; iph2
= LIST_NEXT(iph2
, ph2ofsession_chain
)) {
1179 if (iph2
->approval
) {
1182 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1183 if (pr
->ok
&& pr
->proto_id
== IPSECDOI_PROTO_IPSEC_ESP
) {
1187 if (dir
== IPSEC_DIR_INBOUND
) {
1188 stats
[found
].spi
= pr
->spi
;
1190 stats
[found
].spi
= pr
->spi_p
;
1192 if (++found
== max_stats
) {
1203 ike_session_update_traffic_idle_status (ike_session_t
*session
,
1205 struct sastat
*new_stats
,
1206 u_int32_t max_stats
)
1208 int i
, j
, found
= 0, idle
= 1;
1210 if (!session
|| !new_stats
|| (dir
!= IPSEC_DIR_INBOUND
&& dir
!= IPSEC_DIR_OUTBOUND
)) {
1211 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid args in %s.\n", __FUNCTION__
);
1215 if (!session
->established
|| session
->stopped_by_vpn_controller
|| session
->stop_timestamp
.tv_sec
|| session
->stop_timestamp
.tv_usec
) {
1216 plog(LLV_DEBUG2
, LOCATION
, NULL
, "dropping update on invalid session in %s.\n", __FUNCTION__
);
1220 for (i
= 0; i
< max_stats
; i
++) {
1221 if (dir
== IPSEC_DIR_INBOUND
) {
1222 for (j
= 0; j
< session
->traffic_monitor
.num_in_last_poll
; j
++) {
1223 if (new_stats
[i
].spi
!= session
->traffic_monitor
.in_last_poll
[j
].spi
) {
1227 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.in_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1232 for (j
= 0; j
< session
->traffic_monitor
.num_out_last_poll
; j
++) {
1233 if (new_stats
[i
].spi
!= session
->traffic_monitor
.out_last_poll
[j
].spi
) {
1237 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
!= session
->traffic_monitor
.out_last_poll
[j
].lft_c
.sadb_lifetime_bytes
) {
1242 // new SA.... check for any activity
1244 if (new_stats
[i
].lft_c
.sadb_lifetime_bytes
) {
1245 plog(LLV_DEBUG
, LOCATION
, NULL
, "new SA: dir %d....\n", dir
);
1250 if (dir
== IPSEC_DIR_INBOUND
) {
1251 // overwrite old stats
1252 bzero(session
->traffic_monitor
.in_last_poll
, sizeof(session
->traffic_monitor
.in_last_poll
));
1253 bcopy(new_stats
, session
->traffic_monitor
.in_last_poll
, (max_stats
* sizeof(*new_stats
)));
1254 session
->traffic_monitor
.num_in_last_poll
= max_stats
;
1256 plog(LLV_DEBUG
, LOCATION
, NULL
, "peer sent data....\n");
1257 session
->peer_sent_data_sc_dpd
= 1;
1258 session
->peer_sent_data_sc_idle
= 1;
1261 // overwrite old stats
1262 bzero(session
->traffic_monitor
.out_last_poll
, sizeof(session
->traffic_monitor
.out_last_poll
));
1263 bcopy(new_stats
, session
->traffic_monitor
.out_last_poll
, (max_stats
* sizeof(*new_stats
)));
1264 session
->traffic_monitor
.num_out_last_poll
= max_stats
;
1266 plog(LLV_DEBUG
, LOCATION
, NULL
, "i sent data....\n");
1267 session
->i_sent_data_sc_dpd
= 1;
1268 session
->i_sent_data_sc_idle
= 1;
1272 session
->last_time_data_sc_detected
= time(NULL
);
1274 ike_session_monitor_idle(session
);
1278 ike_session_cleanup (ike_session_t
*session
,
1281 struct ph2handle
*iph2
;
1282 struct ph1handle
*iph1
;
1287 session
->is_dying
= 1;
1289 SCHED_KILL(session
->traffic_monitor
.sc_idle
);
1290 // do ph2's first... we need the ph1s for notifications
1291 for (iph2
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); iph2
; iph2
= LIST_NEXT(iph2
, ph2ofsession_chain
)) {
1292 if (iph2
->status
== PHASE2ST_ESTABLISHED
) {
1293 isakmp_info_send_d2(iph2
);
1295 isakmp_ph2expire(iph2
); // iph2 will go down 1 second later.
1296 ike_session_stopped_by_controller(session
, reason
);
1299 // do the ph1s last.
1300 for (iph1
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); iph1
; iph1
= LIST_NEXT(iph1
, ph1ofsession_chain
)) {
1301 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
1302 isakmp_info_send_d1(iph1
);
1304 isakmp_ph1expire(iph1
);
1307 // send ipsecManager a notification
1308 if (session
->is_cisco_ipsec
&& reason
&& reason
!= ike_session_stopped_by_vpn_disconnect
) {
1310 if (((struct sockaddr
*)&session
->session_id
.remote
)->sa_family
== AF_INET
) {
1311 address
= ((struct sockaddr_in
*)&session
->session_id
.remote
)->sin_addr
.s_addr
;
1316 if (reason
== ike_session_stopped_by_idle
) {
1317 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT
, FROM_LOCAL
, address
, 0, NULL
);
1319 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_INTERNAL_ERROR
, FROM_LOCAL
, address
, 0, NULL
);
1325 ike_session_has_negoing_ph1 (ike_session_t
*session
)
1327 struct ph1handle
*p
;
1330 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1334 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
1335 if (!p
->is_dying
&& p
->status
>= PHASE1ST_START
&& p
->status
<= PHASE1ST_ESTABLISHED
) {
1344 ike_session_has_established_ph1 (ike_session_t
*session
)
1346 struct ph1handle
*p
;
1349 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1353 for (p
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); p
; p
= LIST_NEXT(p
, ph1ofsession_chain
)) {
1354 if (!p
->is_dying
&& p
->status
== PHASE1ST_ESTABLISHED
) {
1363 ike_session_has_negoing_ph2 (ike_session_t
*session
)
1365 struct ph2handle
*p
;
1368 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1372 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1373 if (!p
->is_dying
&& p
->status
>= PHASE2ST_START
&& p
->status
<= PHASE2ST_ESTABLISHED
) {
1382 ike_session_has_established_ph2 (ike_session_t
*session
)
1384 struct ph2handle
*p
;
1387 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1391 for (p
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1392 if (!p
->is_dying
&& p
->status
== PHASE2ST_ESTABLISHED
) {
1401 ike_session_cleanup_ph1s_by_ph2 (struct ph2handle
*iph2
)
1403 struct ph1handle
*iph1
;
1405 if (!iph2
|| !iph2
->parent_session
) {
1406 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1410 // phase1 is no longer useful
1411 for (iph1
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph1tree
); iph1
; iph1
= LIST_NEXT(iph1
, ph1ofsession_chain
)) {
1412 if (iph1
->status
== PHASE1ST_ESTABLISHED
) {
1413 isakmp_info_send_d1(iph1
);
1415 isakmp_ph1expire(iph1
);
1420 ike_session_is_client_ph2_rekey (struct ph2handle
*iph2
)
1422 if (iph2
->parent_session
&&
1423 iph2
->parent_session
->is_client
&&
1425 iph2
->parent_session
->is_cisco_ipsec
) {
1432 ike_session_is_client_ph1_rekey (struct ph1handle
*iph1
)
1434 if (iph1
->parent_session
&&
1435 iph1
->parent_session
->is_client
&&
1437 iph1
->parent_session
->is_cisco_ipsec
) {
1444 ike_session_start_xauth_timer (struct ph1handle
*iph1
)
1446 // if there are no more established ph2s, start a timer to teardown the session
1447 if (iph1
->parent_session
&&
1448 iph1
->parent_session
->is_client
&&
1449 iph1
->parent_session
->is_cisco_ipsec
&&
1450 !iph1
->parent_session
->sc_xauth
) {
1451 iph1
->parent_session
->sc_xauth
= sched_new(300 /* 5 mins */,
1452 ike_session_cleanup_xauth_timeout
,
1453 iph1
->parent_session
);
1458 ike_session_stop_xauth_timer (struct ph1handle
*iph1
)
1460 if (iph1
->parent_session
) {
1461 SCHED_KILL(iph1
->parent_session
->sc_xauth
);
1466 ike_session_is_id_ipany (vchar_t
*ext_id
)
1469 u_int8_t type
; /* ID Type */
1470 u_int8_t proto_id
; /* Protocol ID */
1471 u_int16_t port
; /* Port */
1472 u_int32_t addr
; /* IPv4 address */
1476 /* ignore protocol and port */
1477 id_ptr
= (struct id
*)ext_id
->v
;
1478 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1479 id_ptr
->addr
== 0) {
1481 } else if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR_SUBNET
&&
1482 id_ptr
->mask
== 0 &&
1483 id_ptr
->addr
== 0) {
1486 plog(LLV_DEBUG2
, LOCATION
, NULL
, "not ipany_ids in %s: type %d, addr %x, mask %x.\n",
1487 __FUNCTION__
, id_ptr
->type
, id_ptr
->addr
, id_ptr
->mask
);
1492 ike_session_is_id_portany (vchar_t
*ext_id
)
1495 u_int8_t type
; /* ID Type */
1496 u_int8_t proto_id
; /* Protocol ID */
1497 u_int16_t port
; /* Port */
1498 u_int32_t addr
; /* IPv4 address */
1503 id_ptr
= (struct id
*)ext_id
->v
;
1504 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
&&
1505 id_ptr
->port
== 0) {
1508 plog(LLV_DEBUG2
, LOCATION
, NULL
, "not portany_ids in %s: type %d, port %x.\n",
1509 __FUNCTION__
, id_ptr
->type
, id_ptr
->port
);
1514 ike_session_set_id_portany (vchar_t
*ext_id
)
1517 u_int8_t type
; /* ID Type */
1518 u_int8_t proto_id
; /* Protocol ID */
1519 u_int16_t port
; /* Port */
1520 u_int32_t addr
; /* IPv4 address */
1525 id_ptr
= (struct id
*)ext_id
->v
;
1526 if (id_ptr
->type
== IPSECDOI_ID_IPV4_ADDR
) {
1533 ike_session_cmp_ph2_ids_ipany (vchar_t
*ext_id
,
1536 if (ike_session_is_id_ipany(ext_id
) &&
1537 ike_session_is_id_ipany(ext_id_p
)) {
1544 * ipsec rekeys for l2tp-over-ipsec fail particularly when client is behind nat because the client's configs and policies don't
1545 * match the server's view of the client's address and port.
1546 * servers behave differently when using this address-port info to generate ids during phase2 rekeys, so try to match the incoming id to
1547 * a variety of info saved in the older phase2.
1550 ike_session_cmp_ph2_ids (struct ph2handle
*iph2
,
1551 struct ph2handle
*older_ph2
)
1553 vchar_t
*portany_id
= NULL
;
1554 vchar_t
*portany_id_p
= NULL
;
1556 if (iph2
->id
&& older_ph2
->id
&&
1557 iph2
->id
->l
== older_ph2
->id
->l
&&
1558 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1559 iph2
->id_p
&& older_ph2
->id_p
&&
1560 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1561 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1564 if (iph2
->ext_nat_id
&& older_ph2
->ext_nat_id
&&
1565 iph2
->ext_nat_id
->l
== older_ph2
->ext_nat_id
->l
&&
1566 memcmp(iph2
->ext_nat_id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->ext_nat_id
->l
) == 0 &&
1567 iph2
->ext_nat_id_p
&& older_ph2
->ext_nat_id_p
&&
1568 iph2
->ext_nat_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1569 memcmp(iph2
->ext_nat_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->ext_nat_id_p
->l
) == 0) {
1572 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1573 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1574 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1575 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1576 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1577 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1580 if (iph2
->id
&& older_ph2
->ext_nat_id
&&
1581 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1582 memcmp(iph2
->id
->v
, older_ph2
->ext_nat_id
->v
, iph2
->id
->l
) == 0 &&
1583 iph2
->id_p
&& older_ph2
->id_p
&&
1584 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1585 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1588 if (iph2
->id
&& older_ph2
->id
&&
1589 iph2
->id
->l
== older_ph2
->id
->l
&&
1590 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1591 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1592 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1593 memcmp(iph2
->id_p
->v
, older_ph2
->ext_nat_id_p
->v
, iph2
->id_p
->l
) == 0) {
1597 /* check if the external id has a wildcard port and compare ids accordingly */
1598 if ((older_ph2
->ext_nat_id
&& ike_session_is_id_portany(older_ph2
->ext_nat_id
)) ||
1599 (older_ph2
->ext_nat_id_p
&& ike_session_is_id_portany(older_ph2
->ext_nat_id_p
))) {
1600 // try ignoring ports in iph2->id and iph2->id
1601 if (iph2
->id
&& (portany_id
= vdup(iph2
->id
))) {
1602 ike_session_set_id_portany(portany_id
);
1604 if (iph2
->id_p
&& (portany_id_p
= vdup(iph2
->id_p
))) {
1605 ike_session_set_id_portany(portany_id_p
);
1607 if (portany_id
&& older_ph2
->ext_nat_id
&&
1608 portany_id
->l
== older_ph2
->ext_nat_id
->l
&&
1609 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1610 portany_id_p
&& older_ph2
->ext_nat_id_p
&&
1611 portany_id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1612 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1617 vfree(portany_id_p
);
1621 if (portany_id
&& iph2
->id
&& older_ph2
->ext_nat_id
&&
1622 iph2
->id
->l
== older_ph2
->ext_nat_id
->l
&&
1623 memcmp(portany_id
->v
, older_ph2
->ext_nat_id
->v
, portany_id
->l
) == 0 &&
1624 iph2
->id_p
&& older_ph2
->id_p
&&
1625 iph2
->id_p
->l
== older_ph2
->id_p
->l
&&
1626 memcmp(iph2
->id_p
->v
, older_ph2
->id_p
->v
, iph2
->id_p
->l
) == 0) {
1631 vfree(portany_id_p
);
1635 if (portany_id_p
&& iph2
->id
&& older_ph2
->id
&&
1636 iph2
->id
->l
== older_ph2
->id
->l
&&
1637 memcmp(iph2
->id
->v
, older_ph2
->id
->v
, iph2
->id
->l
) == 0 &&
1638 iph2
->id_p
&& older_ph2
->ext_nat_id_p
&&
1639 iph2
->id_p
->l
== older_ph2
->ext_nat_id_p
->l
&&
1640 memcmp(portany_id_p
->v
, older_ph2
->ext_nat_id_p
->v
, portany_id_p
->l
) == 0) {
1645 vfree(portany_id_p
);
1653 vfree(portany_id_p
);
1660 ike_session_get_sainfo_r (struct ph2handle
*iph2
)
1662 if (iph2
->parent_session
&&
1663 iph2
->parent_session
->is_client
&&
1664 iph2
->id
&& iph2
->id_p
) {
1665 struct ph2handle
*p
;
1666 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1667 plog(LLV_DEBUG2
, LOCATION
, NULL
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1669 for (p
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1670 if (iph2
!= p
&& !p
->is_dying
&& p
->status
>= PHASE2ST_ESTABLISHED
&&
1671 p
->sainfo
&& !p
->sainfo
->to_delete
&& !p
->sainfo
->to_remove
) {
1672 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1674 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1675 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1676 iph2
->sainfo
= p
->sainfo
;
1678 iph2
->spid
= p
->spid
;
1680 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1682 if (p
->ext_nat_id
) {
1683 if (iph2
->ext_nat_id
) {
1684 vfree(iph2
->ext_nat_id
);
1686 iph2
->ext_nat_id
= vdup(p
->ext_nat_id
);
1688 if (p
->ext_nat_id_p
) {
1689 if (iph2
->ext_nat_id_p
) {
1690 vfree(iph2
->ext_nat_id_p
);
1692 iph2
->ext_nat_id_p
= vdup(p
->ext_nat_id_p
);
1703 ike_session_get_proposal_r (struct ph2handle
*iph2
)
1705 if (iph2
->parent_session
&&
1706 iph2
->parent_session
->is_client
&&
1707 iph2
->id
&& iph2
->id_p
) {
1708 struct ph2handle
*p
;
1709 int ipany_ids
= ike_session_cmp_ph2_ids_ipany(iph2
->id
, iph2
->id_p
);
1710 plog(LLV_DEBUG2
, LOCATION
, NULL
, "ipany_ids %d in %s.\n", ipany_ids
, __FUNCTION__
);
1712 for (p
= LIST_FIRST(&iph2
->parent_session
->ikev1_state
.ph2tree
); p
; p
= LIST_NEXT(p
, ph2ofsession_chain
)) {
1713 if (iph2
!= p
&& !p
->is_dying
&& p
->status
>= PHASE2ST_ESTABLISHED
&&
1715 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 found in %s.\n", __FUNCTION__
);
1717 ike_session_cmp_ph2_ids(iph2
, p
) == 0) {
1718 plog(LLV_DEBUG2
, LOCATION
, NULL
, "candidate ph2 matched in %s.\n", __FUNCTION__
);
1719 iph2
->proposal
= dupsaprop(p
->approval
, 1);
1721 iph2
->spid
= p
->spid
;
1723 plog(LLV_DEBUG2
, LOCATION
, NULL
, "%s: pre-assigned spid %d.\n", __FUNCTION__
, iph2
->spid
);
1734 ike_session_update_natt_version (struct ph1handle
*iph1
)
1736 if (iph1
->parent_session
) {
1737 if (iph1
->natt_options
) {
1738 iph1
->parent_session
->natt_version
= iph1
->natt_options
->version
;
1740 iph1
->parent_session
->natt_version
= 0;
1746 ike_session_get_natt_version (struct ph1handle
*iph1
)
1748 if (iph1
->parent_session
) {
1749 return(iph1
->parent_session
->natt_version
);
1755 ike_session_drop_rekey (ike_session_t
*session
, ike_session_rekey_type_t rekey_type
)
1758 if (session
->is_btmm_ipsec
&&
1759 session
->last_time_data_sc_detected
&&
1760 session
->traffic_monitor
.interv_mon
&&
1761 session
->traffic_monitor
.interv_idle
) {
1762 // for btmm: drop ph1/ph2 rekey if session is idle
1763 time_t now
= time(NULL
);
1765 if ((now
- session
->last_time_data_sc_detected
) > (session
->traffic_monitor
.interv_mon
<< 1)) {
1766 plog(LLV_DEBUG2
, LOCATION
, NULL
, "btmm session is idle: drop ph%drekey.\n",
1770 } else if (!session
->is_btmm_ipsec
) {
1771 if (rekey_type
== IKE_SESSION_REKEY_TYPE_PH1
&&
1772 !ike_session_has_negoing_ph2(session
)) {
1773 // for vpn: only drop ph1 if there are no more ph2s.
1774 plog(LLV_DEBUG2
, LOCATION
, NULL
, "vpn session is idle: drop ph1 rekey.\n");
1783 * this is called after racooon receives a 'kIOMessageSystemHasPoweredOn'
1784 * a lot is done to make sure that we don't sweep a session that's already been asserted.
1785 * however, it'll be too bad if the assertion comes after the session has already been swept.
1788 ike_session_sweep_sleepwake (void)
1792 // flag session as dying if all ph1/ph2 are dead/dying
1793 for (p
= LIST_FIRST(&ike_session_tree
); p
; p
= LIST_NEXT(p
, chain
)) {
1795 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of dying session.\n");
1798 SCHED_KILL(p
->sc_xauth
);
1799 if (p
->is_asserted
) {
1800 // for asserted session, traffic monitors will be restared after phase2 becomes established.
1801 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1802 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1803 plog(LLV_DEBUG2
, LOCATION
, NULL
, "skipping sweep of asserted session.\n");
1807 // cleanup any stopped sessions as they will go down
1808 if (p
->stopped_by_vpn_controller
|| p
->stop_timestamp
.tv_sec
|| p
->stop_timestamp
.tv_usec
) {
1809 plog(LLV_DEBUG2
, LOCATION
, NULL
, "sweeping stopped session.\n");
1810 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1814 if (!ike_session_has_established_ph1(p
) && !ike_session_has_established_ph2(p
)) {
1815 plog(LLV_DEBUG2
, LOCATION
, NULL
, "session died while sleeping.\n");
1816 ike_session_cleanup(p
, ike_session_stopped_by_sleepwake
);
1818 if (p
->traffic_monitor
.sc_mon
) {
1819 if (p
->traffic_monitor
.sc_mon
->xtime
<= swept_at
) {
1820 SCHED_KILL(p
->traffic_monitor
.sc_mon
);
1821 if (!p
->is_dying
&& p
->traffic_monitor
.interv_mon
) {
1822 p
->traffic_monitor
.sc_mon
= sched_new(p
->traffic_monitor
.interv_mon
,
1823 ike_session_traffic_cop
,
1828 if (p
->traffic_monitor
.sc_idle
) {
1829 if (p
->traffic_monitor
.sc_idle
->xtime
<= swept_at
) {
1830 SCHED_KILL(p
->traffic_monitor
.sc_idle
);
1831 if (!p
->is_dying
&& p
->traffic_monitor
.interv_idle
) {
1832 p
->traffic_monitor
.sc_idle
= sched_new(p
->traffic_monitor
.interv_idle
,
1833 ike_session_cleanup_idle
,
1842 * this is called after racooon receives an assert command from the controller/pppd.
1843 * this is intended to make racoon prepare to rekey both SAs because a network event occurred.
1844 * in the event of a sleepwake, the assert could happen before or after 'ike_session_sweep_sleepwake'.
1847 ike_session_assert_session (ike_session_t
*session
)
1849 struct ph2handle
*iph2
, *iph2_next
;
1850 struct ph1handle
*iph1
, *iph1_next
;
1852 if (!session
|| session
->is_dying
) {
1853 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1857 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase2s
1858 for (iph2
= LIST_FIRST(&session
->ikev1_state
.ph2tree
); iph2
; iph2
= iph2_next
) {
1859 // take next pointer now, since delete change the underlying ph2tree list
1860 iph2_next
= LIST_NEXT(iph2
, ph2ofsession_chain
);
1861 if (!iph2
->is_dying
&& iph2
->status
< PHASE2ST_EXPIRED
) {
1862 SCHED_KILL(iph2
->sce
);
1865 // delete SAs (in the kernel)
1866 if (iph2
->status
== PHASE2ST_ESTABLISHED
&& iph2
->approval
) {
1869 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1872 plog(LLV_DEBUG
, LOCATION
, NULL
,
1873 "assert: phase2 %s deleted\n",
1874 sadbsecas2str(iph2
->src
, iph2
->dst
, iph2
->satype
, iph2
->spid
, ipsecdoi2pfkey_mode(pr
->encmode
)));
1876 pfkey_send_delete(lcconf
->sock_pfkey
,
1877 ipsecdoi2pfkey_proto(pr
->proto_id
),
1878 ipsecdoi2pfkey_mode(pr
->encmode
),
1879 iph2
->src
, iph2
->dst
, pr
->spi_p
);
1884 iph2
->status
= PHASE2ST_EXPIRED
; // we want to delete SAs without telling the PEER
1885 iph2
->sce
= sched_new(3, ike_session_cleanup_ph2_stub
, iph2
);
1889 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase1s
1890 for (iph1
= LIST_FIRST(&session
->ikev1_state
.ph1tree
); iph1
; iph1
= iph1_next
) {
1891 // take next pointer now, since delete change the underlying ph1tree list
1892 iph1_next
= LIST_NEXT(iph1
, ph1ofsession_chain
);
1893 if (!iph1
->is_dying
&& iph1
->status
< PHASE1ST_EXPIRED
) {
1894 SCHED_KILL(iph1
->sce
);
1895 SCHED_KILL(iph1
->sce_rekey
);
1899 plog(LLV_DEBUG
, LOCATION
, NULL
,
1900 "assert: phase1 %s deleted\n",
1901 isakmp_pindex(&iph1
->index
, 0));
1903 ike_session_unbindph12_from_ph1(iph1
);
1905 iph1
->status
= PHASE1ST_EXPIRED
; // we want to delete SAs without telling the PEER
1906 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
1907 iph1
->sce
= sched_new(5, ike_session_cleanup_ph1_stub
, iph1
);
1910 session
->is_asserted
= 1;
1916 ike_session_assert (struct sockaddr
*local
,
1917 struct sockaddr
*remote
)
1919 ike_session_t
*sess
;
1921 if (!local
|| !remote
) {
1922 plog(LLV_DEBUG2
, LOCATION
, NULL
, "invalid parameters in %s.\n", __FUNCTION__
);
1926 if ((sess
= ike_session_get_session(local
, remote
, FALSE
))) {
1927 return(ike_session_assert_session(sess
));
1933 ike_session_ph2_retransmits (struct ph2handle
*iph2
)
1935 int num_retransmits
;
1937 if (!iph2
->is_dying
&&
1940 iph2
->ph1
->sce_rekey
&& !iph2
->ph1
->sce_rekey
->dead
&&
1941 iph2
->side
== INITIATOR
&&
1942 iph2
->parent_session
&&
1943 !iph2
->parent_session
->is_cisco_ipsec
&& /* not for Cisco */
1944 iph2
->parent_session
->is_client
) {
1945 num_retransmits
= iph2
->ph1
->rmconf
->retry_counter
- iph2
->retry_counter
;
1946 if (num_retransmits
== 3) {
1948 * phase2 negotiation is stalling on retransmits, inspite of a valid ph1.
1949 * one of the following is possible:
1950 * - (0) severe packet loss.
1951 * - (1) the peer is dead.
1952 * - (2) the peer is out of sync hence dropping this phase2 rekey (and perhaps responding with insecure
1953 * invalid-cookie notifications... but those are untrusted and so we can't rekey phase1 off that)
1954 * (2.1) the peer rebooted (or process restarted) and is now alive.
1955 * (2.2) the peer has deleted phase1 without notifying us (or the notification got dropped somehow).
1956 * (2.3) the peer has a policy/bug stopping this phase2 rekey
1958 * in all these cases, one sure way to know is to trigger a phase1 rekey early.
1960 plog(LLV_DEBUG2
, LOCATION
, NULL
, "many phase2 retransmits: try phase1 rekey and this phase2 to quit earlier.\n");
1961 isakmp_ph1rekeyexpire(iph2
->ph1
, TRUE
);
1962 iph2
->retry_counter
= 0;
1968 ike_session_ph1_retransmits (struct ph1handle
*iph1
)
1970 int num_retransmits
;
1972 if (!iph1
->is_dying
&&
1975 iph1
->status
>= PHASE1ST_START
&& iph1
->status
< PHASE1ST_ESTABLISHED
&&
1976 iph1
->side
== INITIATOR
&&
1977 iph1
->parent_session
&&
1978 iph1
->parent_session
->is_client
&&
1979 !ike_session_has_other_negoing_ph1(iph1
->parent_session
, iph1
)) {
1980 num_retransmits
= iph1
->rmconf
->retry_counter
- iph1
->retry_counter
;
1981 if (num_retransmits
== 3) {
1982 plog(LLV_DEBUG2
, LOCATION
, NULL
, "many phase1 retransmits: try quit earlier.\n");
1983 iph1
->retry_counter
= 0;