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