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
32 typedef struct sa_policy_t sa_policy_t
;
35 * Struct used to store information for a policy. This
36 * is needed since we must provide all this information
37 * for deleting a policy...
42 /** subnet address behind peer peer */
44 /** netmask used for net */
49 * Protocol for this policy, such as TCP/UDP/ICMP...
54 typedef struct private_child_sa_t private_child_sa_t
;
57 * Private data of a child_sa_t object.
59 struct private_child_sa_t
{
61 * Public interface of child_sa_t.
66 /** address of peer */
68 /** actual used SPI, 0 if unused */
73 * Allocated SPI for a ESP proposal candidates
75 u_int32_t alloc_esp_spi
;
78 * Allocated SPI for a AH proposal candidates
80 u_int32_t alloc_ah_spi
;
83 * Protocol used to protect this SA, ESP|AH
85 protocol_id_t protocol
;
88 * List containing sa_policy_t objects
90 linked_list_t
*policies
;
93 * reqid used for this child_sa
98 * time, on which SA was installed
103 * Lifetime before rekeying
105 u_int32_t soft_lifetime
;
108 * Lifetime before delete
110 u_int32_t hard_lifetime
;
113 * transaction which is rekeying this CHILD_SA
115 void *rekeying_transaction
;
118 * has this child SA been rekeyed/is rekeying?
123 * Specifies if NAT traversal is used
128 * CHILD_SAs own logger
134 * Implements child_sa_t.get_reqid
136 static u_int32_t
get_reqid(private_child_sa_t
*this)
142 * Implements child_sa_t.get_spi
144 u_int32_t
get_spi(private_child_sa_t
*this, bool inbound
)
150 return this->other
.spi
;
154 * Implements child_sa_t.get_protocol
156 protocol_id_t
get_protocol(private_child_sa_t
*this)
158 return this->protocol
;
162 * Allocate SPI for a single proposal
164 static status_t
alloc_proposal(private_child_sa_t
*this, proposal_t
*proposal
)
166 protocol_id_t protocol
= proposal
->get_protocol(proposal
);
168 if (protocol
== PROTO_AH
)
170 /* get a new spi for AH, if not already done */
171 if (this->alloc_ah_spi
== 0)
173 if (charon
->kernel_interface
->get_spi(
174 charon
->kernel_interface
,
175 this->other
.addr
, this->me
.addr
,
176 PROTO_AH
, this->reqid
,
177 &this->alloc_ah_spi
) != SUCCESS
)
182 proposal
->set_spi(proposal
, this->alloc_ah_spi
);
184 if (protocol
== PROTO_ESP
)
186 /* get a new spi for ESP, if not already done */
187 if (this->alloc_esp_spi
== 0)
189 if (charon
->kernel_interface
->get_spi(
190 charon
->kernel_interface
,
191 this->other
.addr
, this->me
.addr
,
192 PROTO_ESP
, this->reqid
,
193 &this->alloc_esp_spi
) != SUCCESS
)
198 proposal
->set_spi(proposal
, this->alloc_esp_spi
);
205 * Implements child_sa_t.alloc
207 static status_t
alloc(private_child_sa_t
*this, linked_list_t
*proposals
)
209 iterator_t
*iterator
;
210 proposal_t
*proposal
;
212 /* iterator through proposals to update spis */
213 iterator
= proposals
->create_iterator(proposals
, TRUE
);
214 while(iterator
->has_next(iterator
))
216 iterator
->current(iterator
, (void**)&proposal
);
217 if (alloc_proposal(this, proposal
) != SUCCESS
)
219 iterator
->destroy(iterator
);
223 iterator
->destroy(iterator
);
227 static status_t
install(private_child_sa_t
*this, proposal_t
*proposal
, prf_plus_t
*prf_plus
, bool mine
)
230 algorithm_t
*enc_algo
, *int_algo
;
231 algorithm_t enc_algo_none
= {ENCR_UNDEFINED
, 0};
232 algorithm_t int_algo_none
= {AUTH_UNDEFINED
, 0};
238 this->protocol
= proposal
->get_protocol(proposal
);
240 /* now we have to decide which spi to use. Use self allocated, if "mine",
241 * or the one in the proposal, if not "mine" (others). Additionally,
242 * source and dest host switch depending on the role */
245 /* if we have allocated SPIs for AH and ESP, we must delete the unused
247 if (this->protocol
== PROTO_ESP
)
249 this->me
.spi
= this->alloc_esp_spi
;
250 if (this->alloc_ah_spi
)
252 charon
->kernel_interface
->del_sa(charon
->kernel_interface
, this->me
.addr
,
253 this->alloc_ah_spi
, PROTO_AH
);
258 this->me
.spi
= this->alloc_ah_spi
;
259 if (this->alloc_esp_spi
)
261 charon
->kernel_interface
->del_sa(charon
->kernel_interface
, this->me
.addr
,
262 this->alloc_esp_spi
, PROTO_ESP
);
267 src
= this->other
.addr
;
271 this->other
.spi
= proposal
->get_spi(proposal
);
272 spi
= this->other
.spi
;
274 dst
= this->other
.addr
;
277 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "adding %s %s SA",
278 mine ?
"inbound" : "outbound",
279 mapping_find(protocol_id_m
, this->protocol
));
281 /* select encryption algo */
282 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &enc_algo
))
284 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, " using %s for encryption",
285 mapping_find(encryption_algorithm_m
, enc_algo
->algorithm
));
289 enc_algo
= &enc_algo_none
;
292 /* select integrity algo */
293 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &int_algo
))
295 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, " using %s for integrity",
296 mapping_find(integrity_algorithm_m
, int_algo
->algorithm
));
300 int_algo
= &int_algo_none
;
306 natt
= alloca(sizeof(natt_conf_t
));
307 natt
->sport
= src
->get_port(src
);
308 natt
->dport
= dst
->get_port(dst
);
316 /* send SA down to the kernel */
317 this->logger
->log(this->logger
, CONTROL
|LEVEL2
,
318 " SPI 0x%.8x, src %s dst %s",
319 ntohl(spi
), src
->get_address(src
), dst
->get_address(dst
));
320 status
= charon
->kernel_interface
->add_sa(charon
->kernel_interface
,
324 mine ?
this->soft_lifetime
: 0,
327 prf_plus
, natt
, mine
);
329 this->install_time
= time(NULL
);
334 static status_t
add(private_child_sa_t
*this, proposal_t
*proposal
, prf_plus_t
*prf_plus
)
336 u_int32_t outbound_spi
, inbound_spi
;
338 /* backup outbound spi, as alloc overwrites it */
339 outbound_spi
= proposal
->get_spi(proposal
);
341 /* get SPIs inbound SAs */
342 if (alloc_proposal(this, proposal
) != SUCCESS
)
346 inbound_spi
= proposal
->get_spi(proposal
);
348 /* install inbound SAs */
349 if (install(this, proposal
, prf_plus
, TRUE
) != SUCCESS
)
354 /* install outbound SAs, restore spi*/
355 proposal
->set_spi(proposal
, outbound_spi
);
356 if (install(this, proposal
, prf_plus
, FALSE
) != SUCCESS
)
360 proposal
->set_spi(proposal
, inbound_spi
);
365 static status_t
update(private_child_sa_t
*this, proposal_t
*proposal
, prf_plus_t
*prf_plus
)
367 u_int32_t inbound_spi
;
369 /* backup received spi, as install() overwrites it */
370 inbound_spi
= proposal
->get_spi(proposal
);
372 /* install outbound SAs */
373 if (install(this, proposal
, prf_plus
, FALSE
) != SUCCESS
)
379 proposal
->set_spi(proposal
, inbound_spi
);
380 /* install inbound SAs */
381 if (install(this, proposal
, prf_plus
, TRUE
) != SUCCESS
)
389 static status_t
add_policies(private_child_sa_t
*this, linked_list_t
*my_ts_list
, linked_list_t
*other_ts_list
)
391 iterator_t
*my_iter
, *other_iter
;
392 traffic_selector_t
*my_ts
, *other_ts
;
394 /* iterate over both lists */
395 my_iter
= my_ts_list
->create_iterator(my_ts_list
, TRUE
);
396 other_iter
= other_ts_list
->create_iterator(other_ts_list
, TRUE
);
397 while (my_iter
->has_next(my_iter
))
399 my_iter
->current(my_iter
, (void**)&my_ts
);
400 other_iter
->reset(other_iter
);
401 while (other_iter
->has_next(other_iter
))
403 /* set up policies for every entry in my_ts_list to every entry in other_ts_list */
406 u_int16_t from_port
, to_port
;
410 other_iter
->current(other_iter
, (void**)&other_ts
);
412 /* only set up policies if protocol matches, or if one is zero (any) */
413 if (my_ts
->get_protocol(my_ts
) != other_ts
->get_protocol(other_ts
) &&
414 my_ts
->get_protocol(my_ts
) && other_ts
->get_protocol(other_ts
))
416 this->logger
->log(this->logger
, ERROR
,
417 "CHILD_SA policy uses two different protocols, ignored");
420 policy
= malloc_thing(sa_policy_t
);
421 policy
->upper_proto
= max(my_ts
->get_protocol(my_ts
), other_ts
->get_protocol(other_ts
));
423 /* calculate net and ports for local side */
424 family
= my_ts
->get_type(my_ts
) == TS_IPV4_ADDR_RANGE ? AF_INET
: AF_INET6
;
425 from_addr
= my_ts
->get_from_address(my_ts
);
426 from_port
= my_ts
->get_from_port(my_ts
);
427 to_port
= my_ts
->get_to_port(my_ts
);
428 from_port
= (from_port
!= to_port
) ?
0 : from_port
;
429 policy
->me
.net
= host_create_from_chunk(family
, from_addr
, from_port
);
430 policy
->me
.net_mask
= my_ts
->get_netmask(my_ts
);
431 chunk_free(&from_addr
);
433 /* calculate net and ports for remote side */
434 family
= other_ts
->get_type(other_ts
) == TS_IPV4_ADDR_RANGE ? AF_INET
: AF_INET6
;
435 from_addr
= other_ts
->get_from_address(other_ts
);
436 from_port
= other_ts
->get_from_port(other_ts
);
437 to_port
= other_ts
->get_to_port(other_ts
);
438 from_port
= (from_port
!= to_port
) ?
0 : from_port
;
439 policy
->other
.net
= host_create_from_chunk(family
, from_addr
, from_port
);
440 policy
->other
.net_mask
= other_ts
->get_netmask(other_ts
);
441 chunk_free(&from_addr
);
443 /* install 3 policies: out, in and forward */
444 status
= charon
->kernel_interface
->add_policy(charon
->kernel_interface
,
445 this->me
.addr
, this->other
.addr
,
446 policy
->me
.net
, policy
->other
.net
,
447 policy
->me
.net_mask
, policy
->other
.net_mask
,
448 XFRM_POLICY_OUT
, policy
->upper_proto
,
449 this->protocol
, this->reqid
);
451 status
|= charon
->kernel_interface
->add_policy(charon
->kernel_interface
,
452 this->other
.addr
, this->me
.addr
,
453 policy
->other
.net
, policy
->me
.net
,
454 policy
->other
.net_mask
, policy
->me
.net_mask
,
455 XFRM_POLICY_IN
, policy
->upper_proto
,
456 this->protocol
, this->reqid
);
458 status
|= charon
->kernel_interface
->add_policy(charon
->kernel_interface
,
459 this->other
.addr
, this->me
.addr
,
460 policy
->other
.net
, policy
->me
.net
,
461 policy
->other
.net_mask
, policy
->me
.net_mask
,
462 XFRM_POLICY_FWD
, policy
->upper_proto
,
463 this->protocol
, this->reqid
);
465 if (status
!= SUCCESS
)
467 my_iter
->destroy(my_iter
);
468 other_iter
->destroy(other_iter
);
469 policy
->me
.net
->destroy(policy
->me
.net
);
470 policy
->other
.net
->destroy(policy
->other
.net
);
475 /* add it to the policy list, since we want to know which policies we own */
476 this->policies
->insert_last(this->policies
, policy
);
479 my_iter
->destroy(my_iter
);
480 other_iter
->destroy(other_iter
);
485 * Implementation of child_sa_t.set_rekeying_transaction.
487 static void set_rekeying_transaction(private_child_sa_t
*this, void *transaction
)
489 this->rekeying_transaction
= transaction
;
490 this->is_rekeying
= TRUE
;
494 * Implementation of child_sa_t.get_rekeying_transaction.
496 static void* get_rekeying_transaction(private_child_sa_t
*this)
498 return this->rekeying_transaction
;
502 * Implementation of child_sa_t.is_rekeying.
504 static bool is_rekeying(private_child_sa_t
*this)
506 return this->is_rekeying
;
510 * Implementation of child_sa_t.get_use_time
512 static status_t
get_use_time(private_child_sa_t
*this, bool inbound
, time_t *use_time
)
514 iterator_t
*iterator
;
516 struct protoent
*proto
;
517 char proto_buf
[8] = "";
518 char *proto_name
= proto_buf
;
521 *use_time
= UNDEFINED_TIME
;
523 iterator
= this->policies
->create_iterator(this->policies
, TRUE
);
524 while (iterator
->iterate(iterator
, (void**)&policy
))
528 if (policy
->upper_proto
)
530 proto
= getprotobynumber(policy
->upper_proto
);
533 proto_name
= proto
->p_name
;
537 snprintf(proto_buf
, sizeof(proto_buf
), "<%d>", policy
->upper_proto
);
541 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
542 "querying policy: %s/%d==%s==%s/%d",
543 policy
->me
.net
->get_address(policy
->me
.net
), policy
->me
.net_mask
,
545 policy
->other
.net
->get_address(policy
->other
.net
), policy
->other
.net_mask
);
549 status
= charon
->kernel_interface
->query_policy(charon
->kernel_interface
,
550 this->other
.addr
, this->me
.addr
,
551 policy
->other
.net
, policy
->me
.net
,
552 policy
->other
.net_mask
, policy
->me
.net_mask
,
553 XFRM_POLICY_IN
, policy
->upper_proto
,
556 /* also check forward policy in tunnel mode */
557 if (status
== SUCCESS
/*&& mode == TUNNEL XXX */)
561 status
= charon
->kernel_interface
->query_policy(charon
->kernel_interface
,
562 this->other
.addr
, this->me
.addr
,
563 policy
->other
.net
, policy
->me
.net
,
564 policy
->other
.net_mask
, policy
->me
.net_mask
,
565 XFRM_POLICY_FWD
, policy
->upper_proto
,
568 if (status
== SUCCESS
)
576 status
= charon
->kernel_interface
->query_policy(charon
->kernel_interface
,
577 this->me
.addr
, this->other
.addr
,
578 policy
->me
.net
, policy
->other
.net
,
579 policy
->me
.net_mask
, policy
->other
.net_mask
,
580 XFRM_POLICY_OUT
, policy
->upper_proto
,
584 if (status
!= SUCCESS
)
586 iterator
->destroy(iterator
);
590 *use_time
= max(*use_time
, ut
);
592 iterator
->destroy(iterator
);
598 * Implementation of child_sa_t.log_status.
600 static void log_status(private_child_sa_t
*this, logger_t
*logger
, char* name
)
602 iterator_t
*iterator
;
603 char use_in_str
[12] = "unused";
604 char use_out_str
[12] = "unused";
605 char rekey_str
[12] = "disabled";
606 time_t use_in
, use_out
, now
, rekeying
;
610 logger
= this->logger
;
613 get_use_time(this, TRUE
, &use_in
);
616 snprintf(use_in_str
, sizeof(use_in_str
), "%ds", (int)(now
- use_in
));
618 get_use_time(this, FALSE
, &use_out
);
621 snprintf(use_out_str
, sizeof(use_out_str
), "%ds", (int)(now
- use_out
));
623 if (this->soft_lifetime
)
625 rekeying
= this->soft_lifetime
- (now
- this->install_time
);
626 snprintf(rekey_str
, sizeof(rekey_str
), "%ds", (int)rekeying
);
629 logger
->log(logger
, CONTROL
|LEVEL1
,
630 " \"%s\": using %s, SPIs (in/out): 0x%x/0x%x, reqid: %d",
632 this->protocol
== PROTO_ESP ?
"ESP" : "AH",
633 htonl(this->me
.spi
), htonl(this->other
.spi
),
636 logger
->log(logger
, CONTROL
|LEVEL1
,
637 " \"%s\": rekeying: %s, last traffic (in/out): %s/%s",
638 name
, rekey_str
, use_in_str
, use_out_str
);
640 iterator
= this->policies
->create_iterator(this->policies
, TRUE
);
641 while (iterator
->has_next(iterator
))
644 struct protoent
*proto
;
645 char proto_str
[8] = "";
646 char *proto_name
= proto_str
;
647 char my_net_str
[8] = "";
648 char other_net_str
[8] = "";
649 char my_port_str
[8] = "";
650 char other_port_str
[8] = "";
651 u_int16_t my_port
, other_port
;
653 iterator
->current(iterator
, (void**)&policy
);
655 if (policy
->upper_proto
)
657 proto
= getprotobynumber(policy
->upper_proto
);
660 proto_name
= proto
->p_name
;
664 snprintf(proto_str
, sizeof(proto_str
), "%d", policy
->upper_proto
);
667 if (policy
->me
.net_mask
!= 32)
669 snprintf(my_net_str
, sizeof(my_net_str
), "/%d", policy
->me
.net_mask
);
671 if (policy
->other
.net_mask
!= 32)
673 snprintf(other_net_str
, sizeof(other_net_str
), "/%d", policy
->other
.net_mask
);
675 my_port
= policy
->me
.net
->get_port(policy
->me
.net
);
676 other_port
= policy
->other
.net
->get_port(policy
->other
.net
);
679 snprintf(my_port_str
, sizeof(my_port_str
), ":%d", my_port
);
683 snprintf(other_port_str
, sizeof(other_port_str
), ":%d", other_port
);
686 logger
->log(logger
, CONTROL
, " \"%s\": %s%s%s==%s==%s%s%s",
688 policy
->me
.net
->get_address(policy
->me
.net
),
689 my_port_str
, my_net_str
,
691 policy
->other
.net
->get_address(policy
->other
.net
),
692 other_port_str
, other_net_str
);
694 iterator
->destroy(iterator
);
698 * Update the host adress/port of a SA
700 static status_t
update_sa_hosts(private_child_sa_t
*this, host_t
*new_me
, host_t
*new_other
,
701 int my_changes
, int other_changes
, bool mine
)
703 host_t
*src
, *dst
, *new_src
, *new_dst
;
704 int src_changes
, dst_changes
;
710 src
= this->other
.addr
;
714 src_changes
= other_changes
;
715 dst_changes
= my_changes
;
716 spi
= this->other
.spi
;
721 dst
= this->other
.addr
;
724 src_changes
= my_changes
;
725 dst_changes
= other_changes
;
729 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
730 "updating %s SA 0x%x, from %s:%d..%s:%d to %s:%d..%s:%d",
731 mapping_find(protocol_id_m
, this->protocol
), ntohl(spi
),
732 src
->get_address(src
), src
->get_port(src
),
733 dst
->get_address(dst
), dst
->get_port(dst
),
734 new_src
->get_address(new_src
), new_src
->get_port(new_src
),
735 new_dst
->get_address(new_dst
), new_dst
->get_port(new_dst
));
737 status
= charon
->kernel_interface
->update_sa_hosts(
738 charon
->kernel_interface
,
739 src
, dst
, new_src
, new_dst
,
740 src_changes
, dst_changes
,
741 spi
, this->protocol
);
743 if (status
!= SUCCESS
)
751 * Update the host adress/port of a policy
753 static status_t
update_policy_hosts(private_child_sa_t
*this, host_t
*new_me
, host_t
*new_other
)
755 iterator_t
*iterator
;
759 iterator
= this->policies
->create_iterator(this->policies
, TRUE
);
760 while (iterator
->iterate(iterator
, (void**)&policy
))
762 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
763 "updating policy: %s/%d====%s/%d",
764 policy
->me
.net
->get_address(policy
->me
.net
), policy
->me
.net_mask
,
765 policy
->other
.net
->get_address(policy
->other
.net
), policy
->other
.net_mask
);
767 status
= charon
->kernel_interface
->add_policy(
768 charon
->kernel_interface
,
770 policy
->me
.net
, policy
->other
.net
,
771 policy
->me
.net_mask
, policy
->other
.net_mask
,
772 XFRM_POLICY_OUT
, policy
->upper_proto
,
773 this->protocol
, this->reqid
);
775 status
|= charon
->kernel_interface
->add_policy(
776 charon
->kernel_interface
,
778 policy
->other
.net
, policy
->me
.net
,
779 policy
->other
.net_mask
, policy
->me
.net_mask
,
780 XFRM_POLICY_IN
, policy
->upper_proto
,
781 this->protocol
, this->reqid
);
783 status
|= charon
->kernel_interface
->add_policy(
784 charon
->kernel_interface
,
786 policy
->other
.net
, policy
->me
.net
,
787 policy
->other
.net_mask
, policy
->me
.net_mask
,
788 XFRM_POLICY_FWD
, policy
->upper_proto
,
789 this->protocol
, this->reqid
);
791 if (status
!= SUCCESS
)
793 iterator
->destroy(iterator
);
797 iterator
->destroy(iterator
);
803 * Implementation of child_sa_t.update_hosts.
805 static status_t
update_hosts(private_child_sa_t
*this, host_t
*new_me
, host_t
*new_other
,
806 int my_changes
, int other_changes
)
808 if (!my_changes
&& !other_changes
)
813 /* update our (initator) SAs */
814 if (update_sa_hosts(this, new_me
, new_other
, my_changes
, other_changes
, TRUE
) != SUCCESS
)
819 /* update his (responder) SAs */
820 if (update_sa_hosts(this, new_me
, new_other
, my_changes
, other_changes
, FALSE
) != SUCCESS
)
825 /* update policies */
826 if (my_changes
& HOST_DIFF_ADDR
|| other_changes
& HOST_DIFF_ADDR
)
828 if (update_policy_hosts(this, new_me
, new_other
) != SUCCESS
)
837 this->me
.addr
->destroy(this->me
.addr
);
838 this->me
.addr
= new_me
->clone(new_me
);
843 this->other
.addr
->destroy(this->other
.addr
);
844 this->other
.addr
= new_other
->clone(new_other
);
851 * Implementation of child_sa_t.destroy.
853 static void destroy(private_child_sa_t
*this)
857 /* delete SAs in the kernel, if they are set up */
860 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
861 this->me
.addr
, this->me
.spi
, this->protocol
);
863 if (this->alloc_esp_spi
&& this->alloc_esp_spi
!= this->me
.spi
)
865 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
866 this->me
.addr
, this->alloc_esp_spi
, PROTO_ESP
);
868 if (this->alloc_ah_spi
&& this->alloc_ah_spi
!= this->me
.spi
)
870 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
871 this->me
.addr
, this->alloc_ah_spi
, PROTO_AH
);
875 charon
->kernel_interface
->del_sa(charon
->kernel_interface
,
876 this->other
.addr
, this->other
.spi
, this->protocol
);
879 /* delete all policies in the kernel */
880 while (this->policies
->remove_last(this->policies
, (void**)&policy
) == SUCCESS
)
882 if (!this->is_rekeying
)
884 /* let rekeyed policies, as they are used by another child_sa */
885 charon
->kernel_interface
->del_policy(charon
->kernel_interface
,
886 this->me
.addr
, this->other
.addr
,
887 policy
->me
.net
, policy
->other
.net
,
888 policy
->me
.net_mask
, policy
->other
.net_mask
,
889 XFRM_POLICY_OUT
, policy
->upper_proto
);
891 charon
->kernel_interface
->del_policy(charon
->kernel_interface
,
892 this->other
.addr
, this->me
.addr
,
893 policy
->other
.net
, policy
->me
.net
,
894 policy
->other
.net_mask
, policy
->me
.net_mask
,
895 XFRM_POLICY_IN
, policy
->upper_proto
);
897 charon
->kernel_interface
->del_policy(charon
->kernel_interface
,
898 this->other
.addr
, this->me
.addr
,
899 policy
->other
.net
, policy
->me
.net
,
900 policy
->other
.net_mask
, policy
->me
.net_mask
,
901 XFRM_POLICY_FWD
, policy
->upper_proto
);
903 policy
->me
.net
->destroy(policy
->me
.net
);
904 policy
->other
.net
->destroy(policy
->other
.net
);
907 this->policies
->destroy(this->policies
);
909 this->me
.addr
->destroy(this->me
.addr
);
910 this->other
.addr
->destroy(this->other
.addr
);
915 * Described in header.
917 child_sa_t
* child_sa_create(u_int32_t rekey
, host_t
*me
, host_t
* other
,
918 u_int32_t soft_lifetime
, u_int32_t hard_lifetime
,
921 static u_int32_t reqid
= REQID_START
;
922 private_child_sa_t
*this = malloc_thing(private_child_sa_t
);
924 /* public functions */
925 this->public.get_reqid
= (u_int32_t(*)(child_sa_t
*))get_reqid
;
926 this->public.get_spi
= (u_int32_t(*)(child_sa_t
*, bool))get_spi
;
927 this->public.get_protocol
= (protocol_id_t(*)(child_sa_t
*))get_protocol
;
928 this->public.alloc
= (status_t(*)(child_sa_t
*,linked_list_t
*))alloc
;
929 this->public.add
= (status_t(*)(child_sa_t
*,proposal_t
*,prf_plus_t
*))add
;
930 this->public.update
= (status_t(*)(child_sa_t
*,proposal_t
*,prf_plus_t
*))update
;
931 this->public.update_hosts
= (status_t (*)(child_sa_t
*,host_t
*,host_t
*,int,int))update_hosts
;
932 this->public.add_policies
= (status_t (*)(child_sa_t
*, linked_list_t
*,linked_list_t
*))add_policies
;
933 this->public.get_use_time
= (status_t (*)(child_sa_t
*,bool,time_t*))get_use_time
;
934 this->public.set_rekeying_transaction
= (void (*)(child_sa_t
*,void*))set_rekeying_transaction
;
935 this->public.get_rekeying_transaction
= (void* (*)(child_sa_t
*))get_rekeying_transaction
;
936 this->public.is_rekeying
= (bool (*)(child_sa_t
*))is_rekeying
;
937 this->public.log_status
= (void (*)(child_sa_t
*, logger_t
*, char*))log_status
;
938 this->public.destroy
= (void(*)(child_sa_t
*))destroy
;
941 this->logger
= logger_manager
->get_logger(logger_manager
, CHILD_SA
);
942 this->me
.addr
= me
->clone(me
);
943 this->other
.addr
= other
->clone(other
);
946 this->alloc_ah_spi
= 0;
947 this->alloc_esp_spi
= 0;
948 this->use_natt
= use_natt
;
949 this->soft_lifetime
= soft_lifetime
;
950 this->hard_lifetime
= hard_lifetime
;
951 /* reuse old reqid if we are rekeying an existing CHILD_SA */
952 this->reqid
= rekey ? rekey
: ++reqid
;
953 this->policies
= linked_list_create();
954 this->protocol
= PROTO_NONE
;
955 this->rekeying_transaction
= NULL
;
956 this->is_rekeying
= FALSE
;
958 return &this->public;