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