4 * @brief Implementation of child_sa_t.
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33 * String mappings for child_sa_state_t.
35 mapping_t child_sa_state_m
[] = {
36 {CHILD_CREATED
, "CREATED"},
37 {CHILD_INSTALLED
, "INSTALLED"},
38 {CHILD_ROUTED
, "ROUTED"},
39 {CHILD_REKEYING
, "REKEYING"},
40 {CHILD_DELETING
, "DELETING"},
44 typedef struct sa_policy_t sa_policy_t
;
47 * Struct used to store information for a policy. This
48 * is needed since we must provide all this information
49 * for deleting a policy...
53 * Traffic selector for us
55 traffic_selector_t
*my_ts
;
58 * Traffic selector for other
60 traffic_selector_t
*other_ts
;
63 typedef struct private_child_sa_t private_child_sa_t
;
66 * Private data of a child_sa_t object.
68 struct private_child_sa_t
{
70 * Public interface of child_sa_t.
75 * Name of the policy used by this CHILD_SA
80 /** address of peer */
82 /** actual used SPI, 0 if unused */
87 * Allocated SPI for a ESP proposal candidates
89 u_int32_t alloc_esp_spi
;
92 * Allocated SPI for a AH proposal candidates
94 u_int32_t alloc_ah_spi
;
97 * Protocol used to protect this SA, ESP|AH
99 protocol_id_t protocol
;
102 * List containing sa_policy_t objects
104 linked_list_t
*policies
;
107 * Seperate list for local traffic selectors
109 linked_list_t
*my_ts
;
112 * Seperate list for remote traffic selectors
114 linked_list_t
*other_ts
;
117 * reqid used for this child_sa
122 * encryption algorithm used for this SA
124 algorithm_t encryption
;
127 * integrity protection algorithm used for this SA
129 algorithm_t integrity
;
132 * time, on which SA was installed
137 * Lifetime before rekeying
139 u_int32_t soft_lifetime
;
142 * Lifetime before delete
144 u_int32_t hard_lifetime
;
147 * state of the CHILD_SA
149 child_sa_state_t state
;
152 * transaction which is rekeying this CHILD_SA
154 void *rekeying_transaction
;
157 * Specifies if NAT traversal is used
162 * CHILD_SAs own logger
168 * Implementation of child_sa_t.get_name.
170 static char *get_name(private_child_sa_t
*this)
176 * Implementation of child_sa_t.set_name.
178 static void set_name(private_child_sa_t
*this, char* name
)
181 this->name
= strdup(name
);
185 * Implements child_sa_t.get_reqid
187 static u_int32_t
get_reqid(private_child_sa_t
*this)
193 * Implements child_sa_t.get_spi
195 u_int32_t
get_spi(private_child_sa_t
*this, bool inbound
)
201 return this->other
.spi
;
205 * Implements child_sa_t.get_protocol
207 protocol_id_t
get_protocol(private_child_sa_t
*this)
209 return this->protocol
;
213 * Implements child_sa_t.get_state
215 static child_sa_state_t
get_state(private_child_sa_t
*this)
221 * Implements child_sa_t.set_state
223 static void set_state(private_child_sa_t
*this, child_sa_state_t state
)
229 * Allocate SPI for a single proposal
231 static status_t
alloc_proposal(private_child_sa_t
*this, proposal_t
*proposal
)
233 protocol_id_t protocol
= proposal
->get_protocol(proposal
);
235 if (protocol
== PROTO_AH
)
237 /* get a new spi for AH, if not already done */
238 if (this->alloc_ah_spi
== 0)
240 if (charon
->kernel_interface
->get_spi(
241 charon
->kernel_interface
,
242 this->other
.addr
, this->me
.addr
,
243 PROTO_AH
, this->reqid
,
244 &this->alloc_ah_spi
) != SUCCESS
)
249 proposal
->set_spi(proposal
, this->alloc_ah_spi
);
251 if (protocol
== PROTO_ESP
)
253 /* get a new spi for ESP, if not already done */
254 if (this->alloc_esp_spi
== 0)
256 if (charon
->kernel_interface
->get_spi(
257 charon
->kernel_interface
,
258 this->other
.addr
, this->me
.addr
,
259 PROTO_ESP
, this->reqid
,
260 &this->alloc_esp_spi
) != SUCCESS
)
265 proposal
->set_spi(proposal
, this->alloc_esp_spi
);
272 * Implements child_sa_t.alloc
274 static status_t
alloc(private_child_sa_t
*this, linked_list_t
*proposals
)
276 iterator_t
*iterator
;
277 proposal_t
*proposal
;
279 /* iterator through proposals to update spis */
280 iterator
= proposals
->create_iterator(proposals
, TRUE
);
281 while(iterator
->has_next(iterator
))
283 iterator
->current(iterator
, (void**)&proposal
);
284 if (alloc_proposal(this, proposal
) != SUCCESS
)
286 iterator
->destroy(iterator
);
290 iterator
->destroy(iterator
);
294 static status_t
install(private_child_sa_t
*this, proposal_t
*proposal
, prf_plus_t
*prf_plus
, bool mine
)
297 algorithm_t
*enc_algo
, *int_algo
;
298 algorithm_t enc_algo_none
= {ENCR_UNDEFINED
, 0};
299 algorithm_t int_algo_none
= {AUTH_UNDEFINED
, 0};
305 this->protocol
= proposal
->get_protocol(proposal
);
307 /* now we have to decide which spi to use. Use self allocated, if "mine",
308 * or the one in the proposal, if not "mine" (others). Additionally,
309 * source and dest host switch depending on the role */
312 /* if we have allocated SPIs for AH and ESP, we must delete the unused
314 if (this->protocol
== PROTO_ESP
)
316 this->me
.spi
= this->alloc_esp_spi
;
317 if (this->alloc_ah_spi
)
319 charon
->kernel_interface
->del_sa(charon
->kernel_interface
, this->me
.addr
,
320 this->alloc_ah_spi
, PROTO_AH
);
325 this->me
.spi
= this->alloc_ah_spi
;
326 if (this->alloc_esp_spi
)
328 charon
->kernel_interface
->del_sa(charon
->kernel_interface
, this->me
.addr
,
329 this->alloc_esp_spi
, PROTO_ESP
);
334 src
= this->other
.addr
;
338 this->other
.spi
= proposal
->get_spi(proposal
);
339 spi
= this->other
.spi
;
341 dst
= this->other
.addr
;
344 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "adding %s %s SA",
345 mine ?
"inbound" : "outbound",
346 mapping_find(protocol_id_m
, this->protocol
));
348 /* select encryption algo */
349 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &enc_algo
))
351 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, " using %s for encryption",
352 mapping_find(encryption_algorithm_m
, enc_algo
->algorithm
));
356 enc_algo
= &enc_algo_none
;
359 /* select integrity algo */
360 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &int_algo
))
362 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, " using %s for integrity",
363 mapping_find(integrity_algorithm_m
, int_algo
->algorithm
));
367 int_algo
= &int_algo_none
;
373 natt
= alloca(sizeof(natt_conf_t
));
374 natt
->sport
= src
->get_port(src
);
375 natt
->dport
= dst
->get_port(dst
);
383 /* send SA down to the kernel */
384 this->logger
->log(this->logger
, CONTROL
|LEVEL2
,
385 " SPI 0x%.8x, src %s dst %s",
386 ntohl(spi
), src
->get_string(src
), dst
->get_string(dst
));
387 status
= charon
->kernel_interface
->add_sa(charon
->kernel_interface
,
391 mine ?
this->soft_lifetime
: 0,
394 prf_plus
, natt
, mine
);
396 this->encryption
= *enc_algo
;
397 this->integrity
= *int_algo
;
398 this->install_time
= time(NULL
);
403 static status_t
add(private_child_sa_t
*this, proposal_t
*proposal
, prf_plus_t
*prf_plus
)
405 u_int32_t outbound_spi
, inbound_spi
;
407 /* backup outbound spi, as alloc overwrites it */
408 outbound_spi
= proposal
->get_spi(proposal
);
410 /* get SPIs inbound SAs */
411 if (alloc_proposal(this, proposal
) != SUCCESS
)
415 inbound_spi
= proposal
->get_spi(proposal
);
417 /* install inbound SAs */
418 if (install(this, proposal
, prf_plus
, TRUE
) != SUCCESS
)
423 /* install outbound SAs, restore spi*/
424 proposal
->set_spi(proposal
, outbound_spi
);
425 if (install(this, proposal
, prf_plus
, FALSE
) != SUCCESS
)
429 proposal
->set_spi(proposal
, inbound_spi
);
431 this->state
= CHILD_INSTALLED
;
436 static status_t
update(private_child_sa_t
*this, proposal_t
*proposal
, prf_plus_t
*prf_plus
)
438 u_int32_t inbound_spi
;
440 /* backup received spi, as install() overwrites it */
441 inbound_spi
= proposal
->get_spi(proposal
);
443 /* install outbound SAs */
444 if (install(this, proposal
, prf_plus
, FALSE
) != SUCCESS
)
450 proposal
->set_spi(proposal
, inbound_spi
);
451 /* install inbound SAs */
452 if (install(this, proposal
, prf_plus
, TRUE
) != SUCCESS
)
457 this->state
= CHILD_INSTALLED
;
462 static status_t
add_policies(private_child_sa_t
*this, linked_list_t
*my_ts_list
, linked_list_t
*other_ts_list
)
464 iterator_t
*my_iter
, *other_iter
;
465 traffic_selector_t
*my_ts
, *other_ts
;
467 /* iterate over both lists */
468 my_iter
= my_ts_list
->create_iterator(my_ts_list
, TRUE
);
469 other_iter
= other_ts_list
->create_iterator(other_ts_list
, TRUE
);
470 while (my_iter
->has_next(my_iter
))
472 my_iter
->current(my_iter
, (void**)&my_ts
);
473 other_iter
->reset(other_iter
);
474 while (other_iter
->has_next(other_iter
))
476 /* set up policies for every entry in my_ts_list to every entry in other_ts_list */
480 other_iter
->current(other_iter
, (void**)&other_ts
);
482 if (my_ts
->get_type(my_ts
) != other_ts
->get_type(other_ts
))
484 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
485 "CHILD_SA policy uses two different IP families, ignored");
489 /* only set up policies if protocol matches, or if one is zero (any) */
490 if (my_ts
->get_protocol(my_ts
) != other_ts
->get_protocol(other_ts
) &&
491 my_ts
->get_protocol(my_ts
) && other_ts
->get_protocol(other_ts
))
493 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
494 "CHILD_SA policy uses two different protocols, ignored");
498 /* install 3 policies: out, in and forward */
499 status
= charon
->kernel_interface
->add_policy(charon
->kernel_interface
,
500 this->me
.addr
, this->other
.addr
, my_ts
, other_ts
,
501 POLICY_OUT
, this->protocol
, this->reqid
, FALSE
);
503 status
|= charon
->kernel_interface
->add_policy(charon
->kernel_interface
,
504 this->other
.addr
, this->me
.addr
, other_ts
, my_ts
,
505 POLICY_IN
, this->protocol
, this->reqid
, FALSE
);
507 status
|= charon
->kernel_interface
->add_policy(charon
->kernel_interface
,
508 this->other
.addr
, this->me
.addr
, other_ts
, my_ts
,
509 POLICY_FWD
, this->protocol
, this->reqid
, FALSE
);
511 if (status
!= SUCCESS
)
513 my_iter
->destroy(my_iter
);
514 other_iter
->destroy(other_iter
);
518 /* store policy to delete/update them later */
519 policy
= malloc_thing(sa_policy_t
);
520 policy
->my_ts
= my_ts
->clone(my_ts
);
521 policy
->other_ts
= other_ts
->clone(other_ts
);
522 this->policies
->insert_last(this->policies
, (void*)policy
);
523 /* add to separate list to query them via get_*_traffic_selectors() */
524 this->my_ts
->insert_last(this->my_ts
, (void*)policy
->my_ts
);
525 this->other_ts
->insert_last(this->other_ts
, (void*)policy
->other_ts
);
528 my_iter
->destroy(my_iter
);
529 other_iter
->destroy(other_iter
);
531 /* switch to routed state if no SAD entry set up */
532 if (this->state
== CHILD_CREATED
)
534 this->state
= CHILD_ROUTED
;
541 * Implementation of child_sa_t.get_my_traffic_selectors.
543 static linked_list_t
*get_my_traffic_selectors(private_child_sa_t
*this)
549 * Implementation of child_sa_t.get_my_traffic_selectors.
551 static linked_list_t
*get_other_traffic_selectors(private_child_sa_t
*this)
553 return this->other_ts
;
557 * Implementation of child_sa_t.set_rekeying_transaction.
559 static void set_rekeying_transaction(private_child_sa_t
*this, void *transaction
)
561 this->rekeying_transaction
= transaction
;
565 * Implementation of child_sa_t.get_rekeying_transaction.
567 static void* get_rekeying_transaction(private_child_sa_t
*this)
569 return this->rekeying_transaction
;
573 * Implementation of child_sa_t.get_use_time
575 static status_t
get_use_time(private_child_sa_t
*this, bool inbound
, time_t *use_time
)
577 iterator_t
*iterator
;
579 status_t status
= FAILED
;
581 *use_time
= UNDEFINED_TIME
;
583 iterator
= this->policies
->create_iterator(this->policies
, TRUE
);
584 while (iterator
->iterate(iterator
, (void**)&policy
))
588 time_t in
= UNDEFINED_TIME
, fwd
= UNDEFINED_TIME
;
590 status
= charon
->kernel_interface
->query_policy(
591 charon
->kernel_interface
,
592 policy
->other_ts
, policy
->my_ts
,
593 POLICY_IN
, (u_int32_t
*)&in
);
594 status
|= charon
->kernel_interface
->query_policy(
595 charon
->kernel_interface
,
596 policy
->other_ts
, policy
->my_ts
,
597 POLICY_FWD
, (u_int32_t
*)&fwd
);
598 *use_time
= max(in
, fwd
);
602 status
= charon
->kernel_interface
->query_policy(
603 charon
->kernel_interface
,
604 policy
->my_ts
, policy
->other_ts
,
605 POLICY_OUT
, (u_int32_t
*)use_time
);
608 iterator
->destroy(iterator
);
613 * Implementation of child_sa_t.log_status.
615 static void log_status(private_child_sa_t
*this, logger_t
*logger
)
617 iterator_t
*iterator
;
618 char use_in_str
[12] = "unused";
619 char use_out_str
[12] = "unused";
620 char rekey_str
[12] = "disabled";
621 char enc_str
[32] = "";
622 char int_str
[32] = "";
623 u_int32_t use_in
, use_out
, use_fwd
, now
, rekeying
;
628 logger
= this->logger
;
630 now
= (u_int32_t
)time(NULL
);
632 if (this->state
== CHILD_INSTALLED
)
635 status
= charon
->kernel_interface
->query_sa(charon
->kernel_interface
,
636 this->me
.addr
, this->me
.spi
, this->protocol
, &use_in
);
637 if (status
== SUCCESS
&& use_in
)
639 snprintf(use_in_str
, sizeof(use_in_str
), "%ds", now
- use_in
);
641 status
= charon
->kernel_interface
->query_sa(charon
->kernel_interface
,
642 this->other
.addr
, this->other
.spi
, this->protocol
, &use_out
);
643 if (status
== SUCCESS
&& use_out
)
645 snprintf(use_out_str
, sizeof(use_out_str
), "%ds", now
- use_out
);
648 /* calculate rekey times */
649 if (this->soft_lifetime
)
651 rekeying
= this->soft_lifetime
- (now
- this->install_time
);
652 snprintf(rekey_str
, sizeof(rekey_str
), "%ds", (int)rekeying
);
655 /* algorithms used */
656 if (this->protocol
== PROTO_ESP
)
658 if (this->encryption
.key_size
)
660 snprintf(enc_str
, sizeof(enc_str
), "%s-%d,",
661 mapping_find(encryption_algorithm_m
, this->encryption
.algorithm
),
662 this->encryption
.key_size
);
666 snprintf(enc_str
, sizeof(enc_str
), "%s,",
667 mapping_find(encryption_algorithm_m
, this->encryption
.algorithm
));
670 if (this->integrity
.key_size
)
672 snprintf(int_str
, sizeof(int_str
), "%s-%d",
673 mapping_find(integrity_algorithm_m
, this->integrity
.algorithm
),
674 this->integrity
.key_size
);
678 snprintf(int_str
, sizeof(int_str
), "%s",
679 mapping_find(integrity_algorithm_m
, this->integrity
.algorithm
));
682 logger
->log(logger
, CONTROL
|LEVEL1
,
683 " \"%s\": state: %s, reqid: %d, ",
684 this->name
, mapping_find(child_sa_state_m
, this->state
), this->reqid
);
685 logger
->log(logger
, CONTROL
|LEVEL1
,
686 " \"%s\": %s (%s%s), SPIs (in/out): 0x%x/0x%x",
687 this->name
, this->protocol
== PROTO_ESP ?
"ESP" : "AH",
689 htonl(this->me
.spi
), htonl(this->other
.spi
));
690 logger
->log(logger
, CONTROL
|LEVEL1
,
691 " \"%s\": rekeying: %s, key age (in/out): %s/%s",
692 this->name
, rekey_str
, use_in_str
, use_out_str
);
696 logger
->log(logger
, CONTROL
|LEVEL1
, " \"%s\": state: %s, reqid: %d",
697 this->name
, mapping_find(child_sa_state_m
, this->state
),
701 iterator
= this->policies
->create_iterator(this->policies
, TRUE
);
702 while (iterator
->has_next(iterator
))
707 char pol_in_str
[12] = "unused";
708 char pol_out_str
[12] = "unused";
709 char pol_fwd_str
[12] = "unused";
712 iterator
->current(iterator
, (void**)&policy
);
713 my_str
= policy
->my_ts
->get_string(policy
->my_ts
);
714 other_str
= policy
->other_ts
->get_string(policy
->other_ts
);
716 /* query policy times */
717 status
= charon
->kernel_interface
->query_policy(charon
->kernel_interface
,
718 policy
->other_ts
, policy
->my_ts
, POLICY_IN
, &use_in
);
719 if (status
== SUCCESS
&& use_in
)
721 snprintf(pol_in_str
, sizeof(pol_in_str
), "%ds", now
- use_in
);
723 status
= charon
->kernel_interface
->query_policy(charon
->kernel_interface
,
724 policy
->my_ts
, policy
->other_ts
, POLICY_OUT
, &use_out
);
725 if (status
== SUCCESS
&& use_out
)
727 snprintf(pol_out_str
, sizeof(pol_out_str
), "%ds", now
- use_out
);
729 status
= charon
->kernel_interface
->query_policy(charon
->kernel_interface
,
730 policy
->other_ts
, policy
->my_ts
, POLICY_FWD
, &use_fwd
);
731 if (status
== SUCCESS
&& use_fwd
)
733 snprintf(pol_fwd_str
, sizeof(pol_fwd_str
), "%ds", now
- use_fwd
);
736 logger
->log(logger
, CONTROL
,
737 " \"%s\": %s====%s, last use (in/out/fwd): %s/%s/%s",
738 this->name
, my_str
, other_str
, pol_in_str
, pol_out_str
, pol_fwd_str
);
740 iterator
->destroy(iterator
);
744 * Update the host adress/port of a SA
746 static status_t
update_sa_hosts(private_child_sa_t
*this, host_t
*new_me
, host_t
*new_other
,
747 int my_changes
, int other_changes
, bool mine
)
749 host_t
*src
, *dst
, *new_src
, *new_dst
;
750 int src_changes
, dst_changes
;
756 src
= this->other
.addr
;
760 src_changes
= other_changes
;
761 dst_changes
= my_changes
;
762 spi
= this->other
.spi
;
767 dst
= this->other
.addr
;
770 src_changes
= my_changes
;
771 dst_changes
= other_changes
;
775 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
776 "updating %s SA 0x%x, from %s:%d..%s:%d to %s:%d..%s:%d",
777 mapping_find(protocol_id_m
, this->protocol
), ntohl(spi
),
778 src
->get_string(src
), src
->get_port(src
),
779 dst
->get_string(dst
), dst
->get_port(dst
),
780 new_src
->get_string(new_src
), new_src
->get_port(new_src
),
781 new_dst
->get_string(new_dst
), new_dst
->get_port(new_dst
));
783 status
= charon
->kernel_interface
->update_sa(charon
->kernel_interface
,
784 dst
, spi
, this->protocol
,
786 src_changes
, dst_changes
);
788 if (status
!= SUCCESS
)
796 * Update the host adress/port of a policy
798 static status_t
update_policy_hosts(private_child_sa_t
*this, host_t
*new_me
, host_t
*new_other
)
800 iterator_t
*iterator
;
804 iterator
= this->policies
->create_iterator(this->policies
, TRUE
);
805 while (iterator
->iterate(iterator
, (void**)&policy
))
807 status
= charon
->kernel_interface
->add_policy(
808 charon
->kernel_interface
,
810 policy
->my_ts
, policy
->other_ts
,
811 POLICY_OUT
, this->protocol
, this->reqid
, TRUE
);
813 status
|= charon
->kernel_interface
->add_policy(
814 charon
->kernel_interface
,
816 policy
->other_ts
, policy
->my_ts
,
817 POLICY_IN
, this->protocol
, this->reqid
, TRUE
);
819 status
|= charon
->kernel_interface
->add_policy(
820 charon
->kernel_interface
,
822 policy
->other_ts
, policy
->my_ts
,
823 POLICY_FWD
, this->protocol
, this->reqid
, TRUE
);
825 if (status
!= SUCCESS
)
827 iterator
->destroy(iterator
);
831 iterator
->destroy(iterator
);
837 * Implementation of child_sa_t.update_hosts.
839 static status_t
update_hosts(private_child_sa_t
*this, host_t
*new_me
, host_t
*new_other
,
840 host_diff_t my_changes
, host_diff_t other_changes
)
842 if (!my_changes
&& !other_changes
)
847 /* update our (initator) SAs */
848 if (update_sa_hosts(this, new_me
, new_other
, my_changes
, other_changes
, TRUE
) != SUCCESS
)
853 /* update his (responder) SAs */
854 if (update_sa_hosts(this, new_me
, new_other
, my_changes
, other_changes
, FALSE
) != SUCCESS
)
859 /* update policies */
860 if (my_changes
& HOST_DIFF_ADDR
|| other_changes
& HOST_DIFF_ADDR
)
862 if (update_policy_hosts(this, new_me
, new_other
) != SUCCESS
)
871 this->me
.addr
->destroy(this->me
.addr
);
872 this->me
.addr
= new_me
->clone(new_me
);
877 this->other
.addr
->destroy(this->other
.addr
);
878 this->other
.addr
= new_other
->clone(new_other
);
885 * Implementation of child_sa_t.destroy.
887 static void destroy(private_child_sa_t
*this)
891 /* delete SAs in the kernel, if they are set up */
894 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
895 this->me
.addr
, this->me
.spi
, this->protocol
);
897 if (this->alloc_esp_spi
&& this->alloc_esp_spi
!= this->me
.spi
)
899 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
900 this->me
.addr
, this->alloc_esp_spi
, PROTO_ESP
);
902 if (this->alloc_ah_spi
&& this->alloc_ah_spi
!= this->me
.spi
)
904 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
905 this->me
.addr
, this->alloc_ah_spi
, PROTO_AH
);
909 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
910 this->other
.addr
, this->other
.spi
, this->protocol
);
913 /* delete all policies in the kernel */
914 while (this->policies
->remove_last(this->policies
, (void**)&policy
) == SUCCESS
)
916 /* let rekeyed policies, as they are used by another child_sa */
917 charon
->kernel_interface
->del_policy(charon
->kernel_interface
,
918 policy
->my_ts
, policy
->other_ts
,
921 charon
->kernel_interface
->del_policy(charon
->kernel_interface
,
922 policy
->other_ts
, policy
->my_ts
,
925 charon
->kernel_interface
->del_policy(charon
->kernel_interface
,
926 policy
->other_ts
, policy
->my_ts
,
928 policy
->my_ts
->destroy(policy
->my_ts
);
929 policy
->other_ts
->destroy(policy
->other_ts
);
932 this->policies
->destroy(this->policies
);
934 this->my_ts
->destroy(this->my_ts
);
935 this->other_ts
->destroy(this->other_ts
);
936 this->me
.addr
->destroy(this->me
.addr
);
937 this->other
.addr
->destroy(this->other
.addr
);
943 * Described in header.
945 child_sa_t
* child_sa_create(u_int32_t rekey
, host_t
*me
, host_t
* other
,
946 u_int32_t soft_lifetime
, u_int32_t hard_lifetime
,
949 static u_int32_t reqid
= REQID_START
;
950 private_child_sa_t
*this = malloc_thing(private_child_sa_t
);
952 /* public functions */
953 this->public.get_name
= (char*(*)(child_sa_t
*))get_name
;
954 this->public.set_name
= (void(*)(child_sa_t
*,char*))set_name
;
955 this->public.get_reqid
= (u_int32_t(*)(child_sa_t
*))get_reqid
;
956 this->public.get_spi
= (u_int32_t(*)(child_sa_t
*, bool))get_spi
;
957 this->public.get_protocol
= (protocol_id_t(*)(child_sa_t
*))get_protocol
;
958 this->public.alloc
= (status_t(*)(child_sa_t
*,linked_list_t
*))alloc
;
959 this->public.add
= (status_t(*)(child_sa_t
*,proposal_t
*,prf_plus_t
*))add
;
960 this->public.update
= (status_t(*)(child_sa_t
*,proposal_t
*,prf_plus_t
*))update
;
961 this->public.update_hosts
= (status_t (*)(child_sa_t
*,host_t
*,host_t
*,host_diff_t
,host_diff_t
))update_hosts
;
962 this->public.add_policies
= (status_t (*)(child_sa_t
*, linked_list_t
*,linked_list_t
*))add_policies
;
963 this->public.get_my_traffic_selectors
= (linked_list_t
*(*)(child_sa_t
*))get_my_traffic_selectors
;
964 this->public.get_other_traffic_selectors
= (linked_list_t
*(*)(child_sa_t
*))get_other_traffic_selectors
;
965 this->public.get_use_time
= (status_t (*)(child_sa_t
*,bool,time_t*))get_use_time
;
966 this->public.set_rekeying_transaction
= (void (*)(child_sa_t
*,void*))set_rekeying_transaction
;
967 this->public.get_rekeying_transaction
= (void* (*)(child_sa_t
*))get_rekeying_transaction
;
968 this->public.set_state
= (void(*)(child_sa_t
*,child_sa_state_t
))set_state
;
969 this->public.get_state
= (child_sa_state_t(*)(child_sa_t
*))get_state
;
970 this->public.log_status
= (void (*)(child_sa_t
*, logger_t
*))log_status
;
971 this->public.destroy
= (void(*)(child_sa_t
*))destroy
;
974 this->logger
= logger_manager
->get_logger(logger_manager
, CHILD_SA
);
975 this->name
= strdup("(uninitialized)");
976 this->me
.addr
= me
->clone(me
);
977 this->other
.addr
= other
->clone(other
);
980 this->alloc_ah_spi
= 0;
981 this->alloc_esp_spi
= 0;
982 this->use_natt
= use_natt
;
983 this->soft_lifetime
= soft_lifetime
;
984 this->hard_lifetime
= hard_lifetime
;
985 this->state
= CHILD_CREATED
;
986 /* reuse old reqid if we are rekeying an existing CHILD_SA */
987 this->reqid
= rekey ? rekey
: ++reqid
;
988 this->encryption
.algorithm
= ENCR_UNDEFINED
;
989 this->encryption
.key_size
= 0;
990 this->integrity
.algorithm
= AUTH_UNDEFINED
;
991 this->encryption
.key_size
= 0;
992 this->policies
= linked_list_create();
993 this->my_ts
= linked_list_create();
994 this->other_ts
= linked_list_create();
995 this->protocol
= PROTO_NONE
;
996 this->rekeying_transaction
= NULL
;
998 return &this->public;