child-sa: replace get_traffic_selectors() with create_ts_enumerator()
[strongswan.git] / src / libcharon / sa / child_sa.c
1 /*
2 * Copyright (C) 2006-2011 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2006 Daniel Roethlisberger
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #define _GNU_SOURCE
20 #include "child_sa.h"
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <time.h>
25
26 #include <hydra.h>
27 #include <daemon.h>
28
29 ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
30 "CREATED",
31 "ROUTED",
32 "INSTALLING",
33 "INSTALLED",
34 "UPDATING",
35 "REKEYING",
36 "DELETING",
37 "DESTROYING",
38 );
39
40 typedef struct private_child_sa_t private_child_sa_t;
41
42 /**
43 * Private data of a child_sa_t object.
44 */
45 struct private_child_sa_t {
46 /**
47 * Public interface of child_sa_t.
48 */
49 child_sa_t public;
50
51 /**
52 * address of us
53 */
54 host_t *my_addr;
55
56 /**
57 * address of remote
58 */
59 host_t *other_addr;
60
61 /**
62 * our actually used SPI, 0 if unused
63 */
64 u_int32_t my_spi;
65
66 /**
67 * others used SPI, 0 if unused
68 */
69 u_int32_t other_spi;
70
71 /**
72 * our Compression Parameter Index (CPI) used, 0 if unused
73 */
74 u_int16_t my_cpi;
75
76 /**
77 * others Compression Parameter Index (CPI) used, 0 if unused
78 */
79 u_int16_t other_cpi;
80
81 /**
82 * List for local traffic selectors
83 */
84 linked_list_t *my_ts;
85
86 /**
87 * List for remote traffic selectors
88 */
89 linked_list_t *other_ts;
90
91 /**
92 * Protocol used to protect this SA, ESP|AH
93 */
94 protocol_id_t protocol;
95
96 /**
97 * reqid used for this child_sa
98 */
99 u_int32_t reqid;
100
101 /**
102 * inbound mark used for this child_sa
103 */
104 mark_t mark_in;
105
106 /**
107 * outbound mark used for this child_sa
108 */
109 mark_t mark_out;
110
111 /**
112 * absolute time when rekeying is scheduled
113 */
114 time_t rekey_time;
115
116 /**
117 * absolute time when the SA expires
118 */
119 time_t expire_time;
120
121 /**
122 * state of the CHILD_SA
123 */
124 child_sa_state_t state;
125
126 /**
127 * TRUE if this CHILD_SA is used to install trap policies
128 */
129 bool trap;
130
131 /**
132 * Specifies if UDP encapsulation is enabled (NAT traversal)
133 */
134 bool encap;
135
136 /**
137 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
138 */
139 ipcomp_transform_t ipcomp;
140
141 /**
142 * mode this SA uses, tunnel/transport
143 */
144 ipsec_mode_t mode;
145
146 /**
147 * Action to enforce if peer closes the CHILD_SA
148 */
149 action_t close_action;
150
151 /**
152 * Action to enforce if peer is considered dead
153 */
154 action_t dpd_action;
155
156 /**
157 * selected proposal
158 */
159 proposal_t *proposal;
160
161 /**
162 * config used to create this child
163 */
164 child_cfg_t *config;
165
166 /**
167 * time of last use in seconds (inbound)
168 */
169 u_int32_t my_usetime;
170
171 /**
172 * time of last use in seconds (outbound)
173 */
174 u_int32_t other_usetime;
175
176 /**
177 * last number of inbound bytes
178 */
179 u_int64_t my_usebytes;
180
181 /**
182 * last number of outbound bytes
183 */
184 u_int64_t other_usebytes;
185
186 /**
187 * last number of inbound packets
188 */
189 u_int64_t my_usepackets;
190
191 /**
192 * last number of outbound bytes
193 */
194 u_int64_t other_usepackets;
195 };
196
197 /**
198 * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
199 */
200 static inline u_int8_t proto_ike2ip(protocol_id_t protocol)
201 {
202 switch (protocol)
203 {
204 case PROTO_ESP:
205 return IPPROTO_ESP;
206 case PROTO_AH:
207 return IPPROTO_AH;
208 default:
209 return protocol;
210 }
211 }
212
213 METHOD(child_sa_t, get_name, char*,
214 private_child_sa_t *this)
215 {
216 return this->config->get_name(this->config);
217 }
218
219 METHOD(child_sa_t, get_reqid, u_int32_t,
220 private_child_sa_t *this)
221 {
222 return this->reqid;
223 }
224
225 METHOD(child_sa_t, get_config, child_cfg_t*,
226 private_child_sa_t *this)
227 {
228 return this->config;
229 }
230
231 METHOD(child_sa_t, set_state, void,
232 private_child_sa_t *this, child_sa_state_t state)
233 {
234 charon->bus->child_state_change(charon->bus, &this->public, state);
235 this->state = state;
236 }
237
238 METHOD(child_sa_t, get_state, child_sa_state_t,
239 private_child_sa_t *this)
240 {
241 return this->state;
242 }
243
244 METHOD(child_sa_t, get_spi, u_int32_t,
245 private_child_sa_t *this, bool inbound)
246 {
247 return inbound ? this->my_spi : this->other_spi;
248 }
249
250 METHOD(child_sa_t, get_cpi, u_int16_t,
251 private_child_sa_t *this, bool inbound)
252 {
253 return inbound ? this->my_cpi : this->other_cpi;
254 }
255
256 METHOD(child_sa_t, get_protocol, protocol_id_t,
257 private_child_sa_t *this)
258 {
259 return this->protocol;
260 }
261
262 METHOD(child_sa_t, set_protocol, void,
263 private_child_sa_t *this, protocol_id_t protocol)
264 {
265 this->protocol = protocol;
266 }
267
268 METHOD(child_sa_t, get_mode, ipsec_mode_t,
269 private_child_sa_t *this)
270 {
271 return this->mode;
272 }
273
274 METHOD(child_sa_t, set_mode, void,
275 private_child_sa_t *this, ipsec_mode_t mode)
276 {
277 this->mode = mode;
278 }
279
280 METHOD(child_sa_t, has_encap, bool,
281 private_child_sa_t *this)
282 {
283 return this->encap;
284 }
285
286 METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t,
287 private_child_sa_t *this)
288 {
289 return this->ipcomp;
290 }
291
292 METHOD(child_sa_t, set_ipcomp, void,
293 private_child_sa_t *this, ipcomp_transform_t ipcomp)
294 {
295 this->ipcomp = ipcomp;
296 }
297
298 METHOD(child_sa_t, set_close_action, void,
299 private_child_sa_t *this, action_t action)
300 {
301 this->close_action = action;
302 }
303
304 METHOD(child_sa_t, get_close_action, action_t,
305 private_child_sa_t *this)
306 {
307 return this->close_action;
308 }
309
310 METHOD(child_sa_t, set_dpd_action, void,
311 private_child_sa_t *this, action_t action)
312 {
313 this->dpd_action = action;
314 }
315
316 METHOD(child_sa_t, get_dpd_action, action_t,
317 private_child_sa_t *this)
318 {
319 return this->dpd_action;
320 }
321
322 METHOD(child_sa_t, get_proposal, proposal_t*,
323 private_child_sa_t *this)
324 {
325 return this->proposal;
326 }
327
328 METHOD(child_sa_t, set_proposal, void,
329 private_child_sa_t *this, proposal_t *proposal)
330 {
331 this->proposal = proposal->clone(proposal);
332 }
333
334 METHOD(child_sa_t, create_ts_enumerator, enumerator_t*,
335 private_child_sa_t *this, bool local)
336 {
337 if (local)
338 {
339 return this->my_ts->create_enumerator(this->my_ts);
340 }
341 return this->other_ts->create_enumerator(this->other_ts);
342 }
343
344 typedef struct policy_enumerator_t policy_enumerator_t;
345
346 /**
347 * Private policy enumerator
348 */
349 struct policy_enumerator_t {
350 /** implements enumerator_t */
351 enumerator_t public;
352 /** enumerator over own TS */
353 enumerator_t *mine;
354 /** enumerator over others TS */
355 enumerator_t *other;
356 /** list of others TS, to recreate enumerator */
357 linked_list_t *list;
358 /** currently enumerating TS for "me" side */
359 traffic_selector_t *ts;
360 };
361
362 METHOD(enumerator_t, policy_enumerate, bool,
363 policy_enumerator_t *this, traffic_selector_t **my_out,
364 traffic_selector_t **other_out)
365 {
366 traffic_selector_t *other_ts;
367
368 while (this->ts || this->mine->enumerate(this->mine, &this->ts))
369 {
370 if (!this->other->enumerate(this->other, &other_ts))
371 { /* end of others list, restart with new of mine */
372 this->other->destroy(this->other);
373 this->other = this->list->create_enumerator(this->list);
374 this->ts = NULL;
375 continue;
376 }
377 if (this->ts->get_type(this->ts) != other_ts->get_type(other_ts))
378 { /* family mismatch */
379 continue;
380 }
381 if (this->ts->get_protocol(this->ts) &&
382 other_ts->get_protocol(other_ts) &&
383 this->ts->get_protocol(this->ts) != other_ts->get_protocol(other_ts))
384 { /* protocol mismatch */
385 continue;
386 }
387 *my_out = this->ts;
388 *other_out = other_ts;
389 return TRUE;
390 }
391 return FALSE;
392 }
393
394 METHOD(enumerator_t, policy_destroy, void,
395 policy_enumerator_t *this)
396 {
397 this->mine->destroy(this->mine);
398 this->other->destroy(this->other);
399 free(this);
400 }
401
402 METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
403 private_child_sa_t *this)
404 {
405 policy_enumerator_t *e;
406
407 INIT(e,
408 .public = {
409 .enumerate = (void*)_policy_enumerate,
410 .destroy = _policy_destroy,
411 },
412 .mine = this->my_ts->create_enumerator(this->my_ts),
413 .other = this->other_ts->create_enumerator(this->other_ts),
414 .list = this->other_ts,
415 .ts = NULL,
416 );
417
418 return &e->public;
419 }
420
421 /**
422 * update the cached usebytes
423 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
424 * are available, and NOT_SUPPORTED if the kernel interface does not support
425 * querying the usebytes.
426 */
427 static status_t update_usebytes(private_child_sa_t *this, bool inbound)
428 {
429 status_t status = FAILED;
430 u_int64_t bytes, packets;
431 u_int32_t time;
432
433 if (inbound)
434 {
435 if (this->my_spi)
436 {
437 status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
438 this->other_addr, this->my_addr, this->my_spi,
439 proto_ike2ip(this->protocol), this->mark_in,
440 &bytes, &packets, &time);
441 if (status == SUCCESS)
442 {
443 if (bytes > this->my_usebytes)
444 {
445 this->my_usebytes = bytes;
446 this->my_usepackets = packets;
447 if (time)
448 {
449 this->my_usetime = time;
450 }
451 return SUCCESS;
452 }
453 return FAILED;
454 }
455 }
456 }
457 else
458 {
459 if (this->other_spi)
460 {
461 status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
462 this->my_addr, this->other_addr, this->other_spi,
463 proto_ike2ip(this->protocol), this->mark_out,
464 &bytes, &packets, &time);
465 if (status == SUCCESS)
466 {
467 if (bytes > this->other_usebytes)
468 {
469 this->other_usebytes = bytes;
470 this->other_usepackets = packets;
471 if (time)
472 {
473 this->other_usetime = time;
474 }
475 return SUCCESS;
476 }
477 return FAILED;
478 }
479 }
480 }
481 return status;
482 }
483
484 /**
485 * updates the cached usetime
486 */
487 static bool update_usetime(private_child_sa_t *this, bool inbound)
488 {
489 enumerator_t *enumerator;
490 traffic_selector_t *my_ts, *other_ts;
491 u_int32_t last_use = 0;
492
493 enumerator = create_policy_enumerator(this);
494 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
495 {
496 u_int32_t in, out, fwd;
497
498 if (inbound)
499 {
500 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
501 other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS)
502 {
503 last_use = max(last_use, in);
504 }
505 if (this->mode != MODE_TRANSPORT)
506 {
507 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
508 other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS)
509 {
510 last_use = max(last_use, fwd);
511 }
512 }
513 }
514 else
515 {
516 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
517 my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS)
518 {
519 last_use = max(last_use, out);
520 }
521 }
522 }
523 enumerator->destroy(enumerator);
524
525 if (last_use == 0)
526 {
527 return FALSE;
528 }
529 if (inbound)
530 {
531 this->my_usetime = last_use;
532 }
533 else
534 {
535 this->other_usetime = last_use;
536 }
537 return TRUE;
538 }
539
540 METHOD(child_sa_t, get_usestats, void,
541 private_child_sa_t *this, bool inbound,
542 time_t *time, u_int64_t *bytes, u_int64_t *packets)
543 {
544 if ((!bytes && !packets) || update_usebytes(this, inbound) != FAILED)
545 {
546 /* there was traffic since last update or the kernel interface
547 * does not support querying the number of usebytes.
548 */
549 if (time)
550 {
551 if (!update_usetime(this, inbound) && !bytes && !packets)
552 {
553 /* if policy query did not yield a usetime, query SAs instead */
554 update_usebytes(this, inbound);
555 }
556 }
557 }
558 if (time)
559 {
560 *time = inbound ? this->my_usetime : this->other_usetime;
561 }
562 if (bytes)
563 {
564 *bytes = inbound ? this->my_usebytes : this->other_usebytes;
565 }
566 if (packets)
567 {
568 *packets = inbound ? this->my_usepackets : this->other_usepackets;
569 }
570 }
571
572 METHOD(child_sa_t, get_mark, mark_t,
573 private_child_sa_t *this, bool inbound)
574 {
575 if (inbound)
576 {
577 return this->mark_in;
578 }
579 return this->mark_out;
580 }
581
582 METHOD(child_sa_t, get_lifetime, time_t,
583 private_child_sa_t *this, bool hard)
584 {
585 return hard ? this->expire_time : this->rekey_time;
586 }
587
588 METHOD(child_sa_t, alloc_spi, u_int32_t,
589 private_child_sa_t *this, protocol_id_t protocol)
590 {
591 if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
592 this->other_addr, this->my_addr,
593 proto_ike2ip(protocol), this->reqid,
594 &this->my_spi) == SUCCESS)
595 {
596 return this->my_spi;
597 }
598 return 0;
599 }
600
601 METHOD(child_sa_t, alloc_cpi, u_int16_t,
602 private_child_sa_t *this)
603 {
604 if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
605 this->other_addr, this->my_addr,
606 this->reqid, &this->my_cpi) == SUCCESS)
607 {
608 return this->my_cpi;
609 }
610 return 0;
611 }
612
613 METHOD(child_sa_t, install, status_t,
614 private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi,
615 u_int16_t cpi, bool initiator, bool inbound, bool tfcv3,
616 linked_list_t *my_ts, linked_list_t *other_ts)
617 {
618 u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
619 u_int16_t esn = NO_EXT_SEQ_NUMBERS;
620 traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
621 time_t now;
622 lifetime_cfg_t *lifetime;
623 u_int32_t tfc = 0;
624 host_t *src, *dst;
625 status_t status;
626 bool update = FALSE;
627
628 /* now we have to decide which spi to use. Use self allocated, if "in",
629 * or the one in the proposal, if not "in" (others). Additionally,
630 * source and dest host switch depending on the role */
631 if (inbound)
632 {
633 dst = this->my_addr;
634 src = this->other_addr;
635 if (this->my_spi == spi)
636 { /* alloc_spi has been called, do an SA update */
637 update = TRUE;
638 }
639 this->my_spi = spi;
640 this->my_cpi = cpi;
641 }
642 else
643 {
644 src = this->my_addr;
645 dst = this->other_addr;
646 this->other_spi = spi;
647 this->other_cpi = cpi;
648
649 if (tfcv3)
650 {
651 tfc = this->config->get_tfc(this->config);
652 }
653 }
654
655 DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
656 protocol_id_names, this->protocol);
657
658 /* send SA down to the kernel */
659 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
660
661 this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
662 &enc_alg, &size);
663 this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
664 &int_alg, &size);
665 this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
666 &esn, NULL);
667
668 lifetime = this->config->get_lifetime(this->config);
669
670 now = time_monotonic(NULL);
671 if (lifetime->time.rekey)
672 {
673 if (this->rekey_time)
674 {
675 this->rekey_time = min(this->rekey_time, now + lifetime->time.rekey);
676 }
677 else
678 {
679 this->rekey_time = now + lifetime->time.rekey;
680 }
681 }
682 if (lifetime->time.life)
683 {
684 this->expire_time = now + lifetime->time.life;
685 }
686
687 if (!lifetime->time.jitter && !inbound)
688 { /* avoid triggering multiple rekey events */
689 lifetime->time.rekey = 0;
690 }
691
692 /* BEET requires the bound address from the traffic selectors.
693 * TODO: We add just the first traffic selector for now, as the
694 * kernel accepts a single TS per SA only */
695 if (inbound)
696 {
697 my_ts->get_first(my_ts, (void**)&dst_ts);
698 other_ts->get_first(other_ts, (void**)&src_ts);
699 }
700 else
701 {
702 my_ts->get_first(my_ts, (void**)&src_ts);
703 other_ts->get_first(other_ts, (void**)&dst_ts);
704 }
705
706 status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
707 src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
708 inbound ? this->mark_in : this->mark_out, tfc,
709 lifetime, enc_alg, encr, int_alg, integ, this->mode,
710 this->ipcomp, cpi, initiator, this->encap, esn, update,
711 src_ts, dst_ts);
712
713 free(lifetime);
714
715 return status;
716 }
717
718 /**
719 * Install 3 policies: out, in and forward
720 */
721 static status_t install_policies_internal(private_child_sa_t *this,
722 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
723 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
724 ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority)
725 {
726 status_t status = SUCCESS;
727 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
728 my_addr, other_addr, my_ts, other_ts,
729 POLICY_OUT, type, other_sa,
730 this->mark_out, priority);
731
732 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
733 other_addr, my_addr, other_ts, my_ts,
734 POLICY_IN, type, my_sa,
735 this->mark_in, priority);
736 if (this->mode != MODE_TRANSPORT)
737 {
738 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
739 other_addr, my_addr, other_ts, my_ts,
740 POLICY_FWD, type, my_sa,
741 this->mark_in, priority);
742 }
743 return status;
744 }
745
746 /**
747 * Delete 3 policies: out, in and forward
748 */
749 static void del_policies_internal(private_child_sa_t *this,
750 traffic_selector_t *my_ts, traffic_selector_t *other_ts,
751 policy_priority_t priority)
752 {
753 hydra->kernel_interface->del_policy(hydra->kernel_interface,
754 my_ts, other_ts, POLICY_OUT, this->reqid,
755 this->mark_out, priority);
756 hydra->kernel_interface->del_policy(hydra->kernel_interface,
757 other_ts, my_ts, POLICY_IN, this->reqid,
758 this->mark_in, priority);
759 if (this->mode != MODE_TRANSPORT)
760 {
761 hydra->kernel_interface->del_policy(hydra->kernel_interface,
762 other_ts, my_ts, POLICY_FWD, this->reqid,
763 this->mark_in, priority);
764 }
765 }
766
767 METHOD(child_sa_t, add_policies, status_t,
768 private_child_sa_t *this, linked_list_t *my_ts_list,
769 linked_list_t *other_ts_list)
770 {
771 enumerator_t *enumerator;
772 traffic_selector_t *my_ts, *other_ts;
773 status_t status = SUCCESS;
774
775 /* apply traffic selectors */
776 enumerator = my_ts_list->create_enumerator(my_ts_list);
777 while (enumerator->enumerate(enumerator, &my_ts))
778 {
779 this->my_ts->insert_last(this->my_ts, my_ts->clone(my_ts));
780 }
781 enumerator->destroy(enumerator);
782 enumerator = other_ts_list->create_enumerator(other_ts_list);
783 while (enumerator->enumerate(enumerator, &other_ts))
784 {
785 this->other_ts->insert_last(this->other_ts, other_ts->clone(other_ts));
786 }
787 enumerator->destroy(enumerator);
788
789 if (this->config->install_policy(this->config))
790 {
791 policy_priority_t priority;
792 ipsec_sa_cfg_t my_sa = {
793 .mode = this->mode,
794 .reqid = this->reqid,
795 .ipcomp = {
796 .transform = this->ipcomp,
797 },
798 }, other_sa = my_sa;
799
800 my_sa.ipcomp.cpi = this->my_cpi;
801 other_sa.ipcomp.cpi = this->other_cpi;
802
803 if (this->protocol == PROTO_ESP)
804 {
805 my_sa.esp.use = TRUE;
806 my_sa.esp.spi = this->my_spi;
807 other_sa.esp.use = TRUE;
808 other_sa.esp.spi = this->other_spi;
809 }
810 else
811 {
812 my_sa.ah.use = TRUE;
813 my_sa.ah.spi = this->my_spi;
814 other_sa.ah.use = TRUE;
815 other_sa.ah.spi = this->other_spi;
816 }
817
818 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
819 * entry) we install a trap policy */
820 this->trap = this->state == CHILD_CREATED;
821 priority = this->trap ? POLICY_PRIORITY_ROUTED
822 : POLICY_PRIORITY_DEFAULT;
823
824 /* enumerate pairs of traffic selectors */
825 enumerator = create_policy_enumerator(this);
826 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
827 {
828 /* install outbound drop policy to avoid packets leaving unencrypted
829 * when updating policies */
830 if (priority == POLICY_PRIORITY_DEFAULT)
831 {
832 status |= install_policies_internal(this, this->my_addr,
833 this->other_addr, my_ts, other_ts,
834 &my_sa, &other_sa, POLICY_DROP,
835 POLICY_PRIORITY_FALLBACK);
836 }
837
838 /* install policies */
839 status |= install_policies_internal(this, this->my_addr,
840 this->other_addr, my_ts, other_ts,
841 &my_sa, &other_sa, POLICY_IPSEC, priority);
842
843 if (status != SUCCESS)
844 {
845 break;
846 }
847 }
848 enumerator->destroy(enumerator);
849 }
850
851 if (status == SUCCESS && this->trap)
852 {
853 set_state(this, CHILD_ROUTED);
854 }
855 return status;
856 }
857
858 /**
859 * Callback to reinstall a virtual IP
860 */
861 static void reinstall_vip(host_t *vip, host_t *me)
862 {
863 char *iface;
864
865 if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
866 me, &iface))
867 {
868 hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE);
869 hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, -1, iface);
870 free(iface);
871 }
872 }
873
874 METHOD(child_sa_t, update, status_t,
875 private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
876 bool encap)
877 {
878 child_sa_state_t old;
879 bool transport_proxy_mode;
880
881 /* anything changed at all? */
882 if (me->equals(me, this->my_addr) &&
883 other->equals(other, this->other_addr) && this->encap == encap)
884 {
885 return SUCCESS;
886 }
887
888 old = this->state;
889 set_state(this, CHILD_UPDATING);
890 transport_proxy_mode = this->config->use_proxy_mode(this->config) &&
891 this->mode == MODE_TRANSPORT;
892
893 if (!transport_proxy_mode)
894 {
895 /* update our (initiator) SA */
896 if (this->my_spi)
897 {
898 if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
899 this->my_spi, proto_ike2ip(this->protocol),
900 this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
901 this->other_addr, this->my_addr, other, me,
902 this->encap, encap, this->mark_in) == NOT_SUPPORTED)
903 {
904 return NOT_SUPPORTED;
905 }
906 }
907
908 /* update his (responder) SA */
909 if (this->other_spi)
910 {
911 if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
912 this->other_spi, proto_ike2ip(this->protocol),
913 this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
914 this->my_addr, this->other_addr, me, other,
915 this->encap, encap, this->mark_out) == NOT_SUPPORTED)
916 {
917 return NOT_SUPPORTED;
918 }
919 }
920 }
921
922 if (this->config->install_policy(this->config))
923 {
924 ipsec_sa_cfg_t my_sa = {
925 .mode = this->mode,
926 .reqid = this->reqid,
927 .ipcomp = {
928 .transform = this->ipcomp,
929 },
930 }, other_sa = my_sa;
931
932 my_sa.ipcomp.cpi = this->my_cpi;
933 other_sa.ipcomp.cpi = this->other_cpi;
934
935 if (this->protocol == PROTO_ESP)
936 {
937 my_sa.esp.use = TRUE;
938 my_sa.esp.spi = this->my_spi;
939 other_sa.esp.use = TRUE;
940 other_sa.esp.spi = this->other_spi;
941 }
942 else
943 {
944 my_sa.ah.use = TRUE;
945 my_sa.ah.spi = this->my_spi;
946 other_sa.ah.use = TRUE;
947 other_sa.ah.spi = this->other_spi;
948 }
949
950 /* update policies */
951 if (!me->ip_equals(me, this->my_addr) ||
952 !other->ip_equals(other, this->other_addr))
953 {
954 enumerator_t *enumerator;
955 traffic_selector_t *my_ts, *other_ts;
956
957 /* always use high priorities, as hosts getting updated are INSTALLED */
958 enumerator = create_policy_enumerator(this);
959 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
960 {
961 traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
962 /* remove old policies first */
963 del_policies_internal(this, my_ts, other_ts,
964 POLICY_PRIORITY_DEFAULT);
965
966 /* check if we have to update a "dynamic" traffic selector */
967 if (!me->ip_equals(me, this->my_addr) &&
968 my_ts->is_host(my_ts, this->my_addr))
969 {
970 old_my_ts = my_ts->clone(my_ts);
971 my_ts->set_address(my_ts, me);
972 }
973 if (!other->ip_equals(other, this->other_addr) &&
974 other_ts->is_host(other_ts, this->other_addr))
975 {
976 old_other_ts = other_ts->clone(other_ts);
977 other_ts->set_address(other_ts, other);
978 }
979
980 /* we reinstall the virtual IP to handle interface roaming
981 * correctly */
982 vips->invoke_function(vips, (void*)reinstall_vip, me);
983
984 /* reinstall updated policies */
985 install_policies_internal(this, me, other, my_ts, other_ts,
986 &my_sa, &other_sa, POLICY_IPSEC,
987 POLICY_PRIORITY_DEFAULT);
988
989 /* update fallback policies after the new policy is in place */
990 if (old_my_ts || old_other_ts)
991 {
992 del_policies_internal(this, old_my_ts ?: my_ts,
993 old_other_ts ?: other_ts,
994 POLICY_PRIORITY_FALLBACK);
995 install_policies_internal(this, me, other, my_ts, other_ts,
996 &my_sa, &other_sa, POLICY_DROP,
997 POLICY_PRIORITY_FALLBACK);
998 DESTROY_IF(old_my_ts);
999 DESTROY_IF(old_other_ts);
1000 }
1001 }
1002 enumerator->destroy(enumerator);
1003 }
1004 }
1005
1006 if (!transport_proxy_mode)
1007 {
1008 /* apply hosts */
1009 if (!me->equals(me, this->my_addr))
1010 {
1011 this->my_addr->destroy(this->my_addr);
1012 this->my_addr = me->clone(me);
1013 }
1014 if (!other->equals(other, this->other_addr))
1015 {
1016 this->other_addr->destroy(this->other_addr);
1017 this->other_addr = other->clone(other);
1018 }
1019 }
1020
1021 this->encap = encap;
1022 set_state(this, old);
1023
1024 return SUCCESS;
1025 }
1026
1027 METHOD(child_sa_t, destroy, void,
1028 private_child_sa_t *this)
1029 {
1030 enumerator_t *enumerator;
1031 traffic_selector_t *my_ts, *other_ts;
1032 policy_priority_t priority;
1033
1034 priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
1035
1036 set_state(this, CHILD_DESTROYING);
1037
1038 /* delete SAs in the kernel, if they are set up */
1039 if (this->my_spi)
1040 {
1041 /* if CHILD was not established, use PROTO_ESP used during alloc_spi().
1042 * TODO: For AH support, we have to store protocol specific SPI.s */
1043 if (this->protocol == PROTO_NONE)
1044 {
1045 this->protocol = PROTO_ESP;
1046 }
1047 hydra->kernel_interface->del_sa(hydra->kernel_interface,
1048 this->other_addr, this->my_addr, this->my_spi,
1049 proto_ike2ip(this->protocol), this->my_cpi,
1050 this->mark_in);
1051 }
1052 if (this->other_spi)
1053 {
1054 hydra->kernel_interface->del_sa(hydra->kernel_interface,
1055 this->my_addr, this->other_addr, this->other_spi,
1056 proto_ike2ip(this->protocol), this->other_cpi,
1057 this->mark_out);
1058 }
1059
1060 if (this->config->install_policy(this->config))
1061 {
1062 /* delete all policies in the kernel */
1063 enumerator = create_policy_enumerator(this);
1064 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1065 {
1066 del_policies_internal(this, my_ts, other_ts, priority);
1067 if (priority == POLICY_PRIORITY_DEFAULT)
1068 {
1069 del_policies_internal(this, my_ts, other_ts,
1070 POLICY_PRIORITY_FALLBACK);
1071 }
1072 }
1073 enumerator->destroy(enumerator);
1074 }
1075
1076 this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
1077 this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
1078 this->my_addr->destroy(this->my_addr);
1079 this->other_addr->destroy(this->other_addr);
1080 DESTROY_IF(this->proposal);
1081 this->config->destroy(this->config);
1082 free(this);
1083 }
1084
1085 /**
1086 * Described in header.
1087 */
1088 child_sa_t * child_sa_create(host_t *me, host_t* other,
1089 child_cfg_t *config, u_int32_t rekey, bool encap)
1090 {
1091 static refcount_t reqid = 0;
1092 private_child_sa_t *this;
1093
1094 INIT(this,
1095 .public = {
1096 .get_name = _get_name,
1097 .get_reqid = _get_reqid,
1098 .get_config = _get_config,
1099 .get_state = _get_state,
1100 .set_state = _set_state,
1101 .get_spi = _get_spi,
1102 .get_cpi = _get_cpi,
1103 .get_protocol = _get_protocol,
1104 .set_protocol = _set_protocol,
1105 .get_mode = _get_mode,
1106 .set_mode = _set_mode,
1107 .get_proposal = _get_proposal,
1108 .set_proposal = _set_proposal,
1109 .get_lifetime = _get_lifetime,
1110 .get_usestats = _get_usestats,
1111 .get_mark = _get_mark,
1112 .has_encap = _has_encap,
1113 .get_ipcomp = _get_ipcomp,
1114 .set_ipcomp = _set_ipcomp,
1115 .get_close_action = _get_close_action,
1116 .set_close_action = _set_close_action,
1117 .get_dpd_action = _get_dpd_action,
1118 .set_dpd_action = _set_dpd_action,
1119 .alloc_spi = _alloc_spi,
1120 .alloc_cpi = _alloc_cpi,
1121 .install = _install,
1122 .update = _update,
1123 .add_policies = _add_policies,
1124 .create_ts_enumerator = _create_ts_enumerator,
1125 .create_policy_enumerator = _create_policy_enumerator,
1126 .destroy = _destroy,
1127 },
1128 .my_addr = me->clone(me),
1129 .other_addr = other->clone(other),
1130 .encap = encap,
1131 .ipcomp = IPCOMP_NONE,
1132 .state = CHILD_CREATED,
1133 .my_ts = linked_list_create(),
1134 .other_ts = linked_list_create(),
1135 .protocol = PROTO_NONE,
1136 .mode = MODE_TUNNEL,
1137 .close_action = config->get_close_action(config),
1138 .dpd_action = config->get_dpd_action(config),
1139 .reqid = config->get_reqid(config),
1140 .mark_in = config->get_mark(config, TRUE),
1141 .mark_out = config->get_mark(config, FALSE),
1142 );
1143
1144 this->config = config;
1145 config->get_ref(config);
1146
1147 if (!this->reqid)
1148 {
1149 /* reuse old reqid if we are rekeying an existing CHILD_SA */
1150 if (rekey)
1151 {
1152 this->reqid = rekey;
1153 }
1154 else
1155 {
1156 this->reqid = charon->traps->find_reqid(charon->traps, config);
1157 if (!this->reqid)
1158 {
1159 this->reqid = ref_get(&reqid);
1160 }
1161 }
1162 }
1163
1164 if (this->mark_in.value == MARK_REQID)
1165 {
1166 this->mark_in.value = this->reqid;
1167 }
1168 if (this->mark_out.value == MARK_REQID)
1169 {
1170 this->mark_out.value = this->reqid;
1171 }
1172
1173 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1174 if (config->get_mode(config) == MODE_TRANSPORT &&
1175 config->use_proxy_mode(config))
1176 {
1177 ts_type_t type;
1178 int family;
1179 chunk_t addr;
1180 host_t *host;
1181 enumerator_t *enumerator;
1182 linked_list_t *my_ts_list, *other_ts_list, *list;
1183 traffic_selector_t *my_ts, *other_ts;
1184
1185 this->mode = MODE_TRANSPORT;
1186
1187 list = linked_list_create_with_items(me, NULL);
1188 my_ts_list = config->get_traffic_selectors(config, TRUE, NULL, list);
1189 list->destroy(list);
1190 enumerator = my_ts_list->create_enumerator(my_ts_list);
1191 if (enumerator->enumerate(enumerator, &my_ts))
1192 {
1193 if (my_ts->is_host(my_ts, NULL) &&
1194 !my_ts->is_host(my_ts, this->my_addr))
1195 {
1196 type = my_ts->get_type(my_ts);
1197 family = (type == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
1198 addr = my_ts->get_from_address(my_ts);
1199 host = host_create_from_chunk(family, addr, 0);
1200 free(addr.ptr);
1201 DBG1(DBG_CHD, "my address: %H is a transport mode proxy for %H",
1202 this->my_addr, host);
1203 this->my_addr->destroy(this->my_addr);
1204 this->my_addr = host;
1205 }
1206 }
1207 enumerator->destroy(enumerator);
1208 my_ts_list->destroy_offset(my_ts_list, offsetof(traffic_selector_t, destroy));
1209
1210 list = linked_list_create_with_items(other, NULL);
1211 other_ts_list = config->get_traffic_selectors(config, FALSE, NULL, list);
1212 list->destroy(list);
1213 enumerator = other_ts_list->create_enumerator(other_ts_list);
1214 if (enumerator->enumerate(enumerator, &other_ts))
1215 {
1216 if (other_ts->is_host(other_ts, NULL) &&
1217 !other_ts->is_host(other_ts, this->other_addr))
1218 {
1219 type = other_ts->get_type(other_ts);
1220 family = (type == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
1221 addr = other_ts->get_from_address(other_ts);
1222 host = host_create_from_chunk(family, addr, 0);
1223 free(addr.ptr);
1224 DBG1(DBG_CHD, "other address: %H is a transport mode proxy for %H",
1225 this->other_addr, host);
1226 this->other_addr->destroy(this->other_addr);
1227 this->other_addr = host;
1228 }
1229 }
1230 enumerator->destroy(enumerator);
1231 other_ts_list->destroy_offset(other_ts_list, offsetof(traffic_selector_t, destroy));
1232 }
1233
1234 return &this->public;
1235 }