ike: reuse the reqid of an installed trap having the same config
[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, get_traffic_selectors, linked_list_t*,
335 private_child_sa_t *this, bool local)
336 {
337 return local ? this->my_ts : this->other_ts;
338 }
339
340 typedef struct policy_enumerator_t policy_enumerator_t;
341
342 /**
343 * Private policy enumerator
344 */
345 struct policy_enumerator_t {
346 /** implements enumerator_t */
347 enumerator_t public;
348 /** enumerator over own TS */
349 enumerator_t *mine;
350 /** enumerator over others TS */
351 enumerator_t *other;
352 /** list of others TS, to recreate enumerator */
353 linked_list_t *list;
354 /** currently enumerating TS for "me" side */
355 traffic_selector_t *ts;
356 };
357
358 METHOD(enumerator_t, policy_enumerate, bool,
359 policy_enumerator_t *this, traffic_selector_t **my_out,
360 traffic_selector_t **other_out)
361 {
362 traffic_selector_t *other_ts;
363
364 while (this->ts || this->mine->enumerate(this->mine, &this->ts))
365 {
366 if (!this->other->enumerate(this->other, &other_ts))
367 { /* end of others list, restart with new of mine */
368 this->other->destroy(this->other);
369 this->other = this->list->create_enumerator(this->list);
370 this->ts = NULL;
371 continue;
372 }
373 if (this->ts->get_type(this->ts) != other_ts->get_type(other_ts))
374 { /* family mismatch */
375 continue;
376 }
377 if (this->ts->get_protocol(this->ts) &&
378 other_ts->get_protocol(other_ts) &&
379 this->ts->get_protocol(this->ts) != other_ts->get_protocol(other_ts))
380 { /* protocol mismatch */
381 continue;
382 }
383 *my_out = this->ts;
384 *other_out = other_ts;
385 return TRUE;
386 }
387 return FALSE;
388 }
389
390 METHOD(enumerator_t, policy_destroy, void,
391 policy_enumerator_t *this)
392 {
393 this->mine->destroy(this->mine);
394 this->other->destroy(this->other);
395 free(this);
396 }
397
398 METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
399 private_child_sa_t *this)
400 {
401 policy_enumerator_t *e;
402
403 INIT(e,
404 .public = {
405 .enumerate = (void*)_policy_enumerate,
406 .destroy = _policy_destroy,
407 },
408 .mine = this->my_ts->create_enumerator(this->my_ts),
409 .other = this->other_ts->create_enumerator(this->other_ts),
410 .list = this->other_ts,
411 .ts = NULL,
412 );
413
414 return &e->public;
415 }
416
417 /**
418 * update the cached usebytes
419 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
420 * are available, and NOT_SUPPORTED if the kernel interface does not support
421 * querying the usebytes.
422 */
423 static status_t update_usebytes(private_child_sa_t *this, bool inbound)
424 {
425 status_t status = FAILED;
426 u_int64_t bytes, packets;
427 u_int32_t time;
428
429 if (inbound)
430 {
431 if (this->my_spi)
432 {
433 status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
434 this->other_addr, this->my_addr, this->my_spi,
435 proto_ike2ip(this->protocol), this->mark_in,
436 &bytes, &packets, &time);
437 if (status == SUCCESS)
438 {
439 if (bytes > this->my_usebytes)
440 {
441 this->my_usebytes = bytes;
442 this->my_usepackets = packets;
443 if (time)
444 {
445 this->my_usetime = time;
446 }
447 return SUCCESS;
448 }
449 return FAILED;
450 }
451 }
452 }
453 else
454 {
455 if (this->other_spi)
456 {
457 status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
458 this->my_addr, this->other_addr, this->other_spi,
459 proto_ike2ip(this->protocol), this->mark_out,
460 &bytes, &packets, &time);
461 if (status == SUCCESS)
462 {
463 if (bytes > this->other_usebytes)
464 {
465 this->other_usebytes = bytes;
466 this->other_usepackets = packets;
467 if (time)
468 {
469 this->other_usetime = time;
470 }
471 return SUCCESS;
472 }
473 return FAILED;
474 }
475 }
476 }
477 return status;
478 }
479
480 /**
481 * updates the cached usetime
482 */
483 static bool update_usetime(private_child_sa_t *this, bool inbound)
484 {
485 enumerator_t *enumerator;
486 traffic_selector_t *my_ts, *other_ts;
487 u_int32_t last_use = 0;
488
489 enumerator = create_policy_enumerator(this);
490 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
491 {
492 u_int32_t in, out, fwd;
493
494 if (inbound)
495 {
496 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
497 other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS)
498 {
499 last_use = max(last_use, in);
500 }
501 if (this->mode != MODE_TRANSPORT)
502 {
503 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
504 other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS)
505 {
506 last_use = max(last_use, fwd);
507 }
508 }
509 }
510 else
511 {
512 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
513 my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS)
514 {
515 last_use = max(last_use, out);
516 }
517 }
518 }
519 enumerator->destroy(enumerator);
520
521 if (last_use == 0)
522 {
523 return FALSE;
524 }
525 if (inbound)
526 {
527 this->my_usetime = last_use;
528 }
529 else
530 {
531 this->other_usetime = last_use;
532 }
533 return TRUE;
534 }
535
536 METHOD(child_sa_t, get_usestats, void,
537 private_child_sa_t *this, bool inbound,
538 time_t *time, u_int64_t *bytes, u_int64_t *packets)
539 {
540 if ((!bytes && !packets) || update_usebytes(this, inbound) != FAILED)
541 {
542 /* there was traffic since last update or the kernel interface
543 * does not support querying the number of usebytes.
544 */
545 if (time)
546 {
547 if (!update_usetime(this, inbound) && !bytes && !packets)
548 {
549 /* if policy query did not yield a usetime, query SAs instead */
550 update_usebytes(this, inbound);
551 }
552 }
553 }
554 if (time)
555 {
556 *time = inbound ? this->my_usetime : this->other_usetime;
557 }
558 if (bytes)
559 {
560 *bytes = inbound ? this->my_usebytes : this->other_usebytes;
561 }
562 if (packets)
563 {
564 *packets = inbound ? this->my_usepackets : this->other_usepackets;
565 }
566 }
567
568 METHOD(child_sa_t, get_mark, mark_t,
569 private_child_sa_t *this, bool inbound)
570 {
571 if (inbound)
572 {
573 return this->mark_in;
574 }
575 return this->mark_out;
576 }
577
578 METHOD(child_sa_t, get_lifetime, time_t,
579 private_child_sa_t *this, bool hard)
580 {
581 return hard ? this->expire_time : this->rekey_time;
582 }
583
584 METHOD(child_sa_t, alloc_spi, u_int32_t,
585 private_child_sa_t *this, protocol_id_t protocol)
586 {
587 if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
588 this->other_addr, this->my_addr,
589 proto_ike2ip(protocol), this->reqid,
590 &this->my_spi) == SUCCESS)
591 {
592 return this->my_spi;
593 }
594 return 0;
595 }
596
597 METHOD(child_sa_t, alloc_cpi, u_int16_t,
598 private_child_sa_t *this)
599 {
600 if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
601 this->other_addr, this->my_addr,
602 this->reqid, &this->my_cpi) == SUCCESS)
603 {
604 return this->my_cpi;
605 }
606 return 0;
607 }
608
609 METHOD(child_sa_t, install, status_t,
610 private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi,
611 u_int16_t cpi, bool initiator, bool inbound, bool tfcv3,
612 linked_list_t *my_ts, linked_list_t *other_ts)
613 {
614 u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
615 u_int16_t esn = NO_EXT_SEQ_NUMBERS;
616 traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
617 time_t now;
618 lifetime_cfg_t *lifetime;
619 u_int32_t tfc = 0;
620 host_t *src, *dst;
621 status_t status;
622 bool update = FALSE;
623
624 /* now we have to decide which spi to use. Use self allocated, if "in",
625 * or the one in the proposal, if not "in" (others). Additionally,
626 * source and dest host switch depending on the role */
627 if (inbound)
628 {
629 dst = this->my_addr;
630 src = this->other_addr;
631 if (this->my_spi == spi)
632 { /* alloc_spi has been called, do an SA update */
633 update = TRUE;
634 }
635 this->my_spi = spi;
636 this->my_cpi = cpi;
637 }
638 else
639 {
640 src = this->my_addr;
641 dst = this->other_addr;
642 this->other_spi = spi;
643 this->other_cpi = cpi;
644
645 if (tfcv3)
646 {
647 tfc = this->config->get_tfc(this->config);
648 }
649 }
650
651 DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
652 protocol_id_names, this->protocol);
653
654 /* send SA down to the kernel */
655 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
656
657 this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
658 &enc_alg, &size);
659 this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
660 &int_alg, &size);
661 this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
662 &esn, NULL);
663
664 lifetime = this->config->get_lifetime(this->config);
665
666 now = time_monotonic(NULL);
667 if (lifetime->time.rekey)
668 {
669 if (this->rekey_time)
670 {
671 this->rekey_time = min(this->rekey_time, now + lifetime->time.rekey);
672 }
673 else
674 {
675 this->rekey_time = now + lifetime->time.rekey;
676 }
677 }
678 if (lifetime->time.life)
679 {
680 this->expire_time = now + lifetime->time.life;
681 }
682
683 if (!lifetime->time.jitter && !inbound)
684 { /* avoid triggering multiple rekey events */
685 lifetime->time.rekey = 0;
686 }
687
688 /* BEET requires the bound address from the traffic selectors.
689 * TODO: We add just the first traffic selector for now, as the
690 * kernel accepts a single TS per SA only */
691 if (inbound)
692 {
693 my_ts->get_first(my_ts, (void**)&dst_ts);
694 other_ts->get_first(other_ts, (void**)&src_ts);
695 }
696 else
697 {
698 my_ts->get_first(my_ts, (void**)&src_ts);
699 other_ts->get_first(other_ts, (void**)&dst_ts);
700 }
701
702 status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
703 src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
704 inbound ? this->mark_in : this->mark_out, tfc,
705 lifetime, enc_alg, encr, int_alg, integ, this->mode,
706 this->ipcomp, cpi, initiator, this->encap, esn, update,
707 src_ts, dst_ts);
708
709 free(lifetime);
710
711 return status;
712 }
713
714 /**
715 * Install 3 policies: out, in and forward
716 */
717 static status_t install_policies_internal(private_child_sa_t *this,
718 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
719 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
720 ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority)
721 {
722 status_t status = SUCCESS;
723 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
724 my_addr, other_addr, my_ts, other_ts,
725 POLICY_OUT, type, other_sa,
726 this->mark_out, priority);
727
728 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
729 other_addr, my_addr, other_ts, my_ts,
730 POLICY_IN, type, my_sa,
731 this->mark_in, priority);
732 if (this->mode != MODE_TRANSPORT)
733 {
734 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
735 other_addr, my_addr, other_ts, my_ts,
736 POLICY_FWD, type, my_sa,
737 this->mark_in, priority);
738 }
739 return status;
740 }
741
742 /**
743 * Delete 3 policies: out, in and forward
744 */
745 static void del_policies_internal(private_child_sa_t *this,
746 traffic_selector_t *my_ts, traffic_selector_t *other_ts,
747 policy_priority_t priority)
748 {
749 hydra->kernel_interface->del_policy(hydra->kernel_interface,
750 my_ts, other_ts, POLICY_OUT, this->reqid,
751 this->mark_out, priority);
752 hydra->kernel_interface->del_policy(hydra->kernel_interface,
753 other_ts, my_ts, POLICY_IN, this->reqid,
754 this->mark_in, priority);
755 if (this->mode != MODE_TRANSPORT)
756 {
757 hydra->kernel_interface->del_policy(hydra->kernel_interface,
758 other_ts, my_ts, POLICY_FWD, this->reqid,
759 this->mark_in, priority);
760 }
761 }
762
763 METHOD(child_sa_t, add_policies, status_t,
764 private_child_sa_t *this, linked_list_t *my_ts_list,
765 linked_list_t *other_ts_list)
766 {
767 enumerator_t *enumerator;
768 traffic_selector_t *my_ts, *other_ts;
769 status_t status = SUCCESS;
770
771 /* apply traffic selectors */
772 enumerator = my_ts_list->create_enumerator(my_ts_list);
773 while (enumerator->enumerate(enumerator, &my_ts))
774 {
775 this->my_ts->insert_last(this->my_ts, my_ts->clone(my_ts));
776 }
777 enumerator->destroy(enumerator);
778 enumerator = other_ts_list->create_enumerator(other_ts_list);
779 while (enumerator->enumerate(enumerator, &other_ts))
780 {
781 this->other_ts->insert_last(this->other_ts, other_ts->clone(other_ts));
782 }
783 enumerator->destroy(enumerator);
784
785 if (this->config->install_policy(this->config))
786 {
787 policy_priority_t priority;
788 ipsec_sa_cfg_t my_sa = {
789 .mode = this->mode,
790 .reqid = this->reqid,
791 .ipcomp = {
792 .transform = this->ipcomp,
793 },
794 }, other_sa = my_sa;
795
796 my_sa.ipcomp.cpi = this->my_cpi;
797 other_sa.ipcomp.cpi = this->other_cpi;
798
799 if (this->protocol == PROTO_ESP)
800 {
801 my_sa.esp.use = TRUE;
802 my_sa.esp.spi = this->my_spi;
803 other_sa.esp.use = TRUE;
804 other_sa.esp.spi = this->other_spi;
805 }
806 else
807 {
808 my_sa.ah.use = TRUE;
809 my_sa.ah.spi = this->my_spi;
810 other_sa.ah.use = TRUE;
811 other_sa.ah.spi = this->other_spi;
812 }
813
814 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
815 * entry) we install a trap policy */
816 this->trap = this->state == CHILD_CREATED;
817 priority = this->trap ? POLICY_PRIORITY_ROUTED
818 : POLICY_PRIORITY_DEFAULT;
819
820 /* enumerate pairs of traffic selectors */
821 enumerator = create_policy_enumerator(this);
822 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
823 {
824 /* install outbound drop policy to avoid packets leaving unencrypted
825 * when updating policies */
826 if (priority == POLICY_PRIORITY_DEFAULT)
827 {
828 status |= install_policies_internal(this, this->my_addr,
829 this->other_addr, my_ts, other_ts,
830 &my_sa, &other_sa, POLICY_DROP,
831 POLICY_PRIORITY_FALLBACK);
832 }
833
834 /* install policies */
835 status |= install_policies_internal(this, this->my_addr,
836 this->other_addr, my_ts, other_ts,
837 &my_sa, &other_sa, POLICY_IPSEC, priority);
838
839 if (status != SUCCESS)
840 {
841 break;
842 }
843 }
844 enumerator->destroy(enumerator);
845 }
846
847 if (status == SUCCESS && this->trap)
848 {
849 set_state(this, CHILD_ROUTED);
850 }
851 return status;
852 }
853
854 /**
855 * Callback to reinstall a virtual IP
856 */
857 static void reinstall_vip(host_t *vip, host_t *me)
858 {
859 char *iface;
860
861 if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
862 me, &iface))
863 {
864 hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE);
865 hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, -1, iface);
866 free(iface);
867 }
868 }
869
870 METHOD(child_sa_t, update, status_t,
871 private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
872 bool encap)
873 {
874 child_sa_state_t old;
875 bool transport_proxy_mode;
876
877 /* anything changed at all? */
878 if (me->equals(me, this->my_addr) &&
879 other->equals(other, this->other_addr) && this->encap == encap)
880 {
881 return SUCCESS;
882 }
883
884 old = this->state;
885 set_state(this, CHILD_UPDATING);
886 transport_proxy_mode = this->config->use_proxy_mode(this->config) &&
887 this->mode == MODE_TRANSPORT;
888
889 if (!transport_proxy_mode)
890 {
891 /* update our (initiator) SA */
892 if (this->my_spi)
893 {
894 if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
895 this->my_spi, proto_ike2ip(this->protocol),
896 this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
897 this->other_addr, this->my_addr, other, me,
898 this->encap, encap, this->mark_in) == NOT_SUPPORTED)
899 {
900 return NOT_SUPPORTED;
901 }
902 }
903
904 /* update his (responder) SA */
905 if (this->other_spi)
906 {
907 if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
908 this->other_spi, proto_ike2ip(this->protocol),
909 this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
910 this->my_addr, this->other_addr, me, other,
911 this->encap, encap, this->mark_out) == NOT_SUPPORTED)
912 {
913 return NOT_SUPPORTED;
914 }
915 }
916 }
917
918 if (this->config->install_policy(this->config))
919 {
920 ipsec_sa_cfg_t my_sa = {
921 .mode = this->mode,
922 .reqid = this->reqid,
923 .ipcomp = {
924 .transform = this->ipcomp,
925 },
926 }, other_sa = my_sa;
927
928 my_sa.ipcomp.cpi = this->my_cpi;
929 other_sa.ipcomp.cpi = this->other_cpi;
930
931 if (this->protocol == PROTO_ESP)
932 {
933 my_sa.esp.use = TRUE;
934 my_sa.esp.spi = this->my_spi;
935 other_sa.esp.use = TRUE;
936 other_sa.esp.spi = this->other_spi;
937 }
938 else
939 {
940 my_sa.ah.use = TRUE;
941 my_sa.ah.spi = this->my_spi;
942 other_sa.ah.use = TRUE;
943 other_sa.ah.spi = this->other_spi;
944 }
945
946 /* update policies */
947 if (!me->ip_equals(me, this->my_addr) ||
948 !other->ip_equals(other, this->other_addr))
949 {
950 enumerator_t *enumerator;
951 traffic_selector_t *my_ts, *other_ts;
952
953 /* always use high priorities, as hosts getting updated are INSTALLED */
954 enumerator = create_policy_enumerator(this);
955 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
956 {
957 traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
958 /* remove old policies first */
959 del_policies_internal(this, my_ts, other_ts,
960 POLICY_PRIORITY_DEFAULT);
961
962 /* check if we have to update a "dynamic" traffic selector */
963 if (!me->ip_equals(me, this->my_addr) &&
964 my_ts->is_host(my_ts, this->my_addr))
965 {
966 old_my_ts = my_ts->clone(my_ts);
967 my_ts->set_address(my_ts, me);
968 }
969 if (!other->ip_equals(other, this->other_addr) &&
970 other_ts->is_host(other_ts, this->other_addr))
971 {
972 old_other_ts = other_ts->clone(other_ts);
973 other_ts->set_address(other_ts, other);
974 }
975
976 /* we reinstall the virtual IP to handle interface roaming
977 * correctly */
978 vips->invoke_function(vips, (void*)reinstall_vip, me);
979
980 /* reinstall updated policies */
981 install_policies_internal(this, me, other, my_ts, other_ts,
982 &my_sa, &other_sa, POLICY_IPSEC,
983 POLICY_PRIORITY_DEFAULT);
984
985 /* update fallback policies after the new policy is in place */
986 if (old_my_ts || old_other_ts)
987 {
988 del_policies_internal(this, old_my_ts ?: my_ts,
989 old_other_ts ?: other_ts,
990 POLICY_PRIORITY_FALLBACK);
991 install_policies_internal(this, me, other, my_ts, other_ts,
992 &my_sa, &other_sa, POLICY_DROP,
993 POLICY_PRIORITY_FALLBACK);
994 DESTROY_IF(old_my_ts);
995 DESTROY_IF(old_other_ts);
996 }
997 }
998 enumerator->destroy(enumerator);
999 }
1000 }
1001
1002 if (!transport_proxy_mode)
1003 {
1004 /* apply hosts */
1005 if (!me->equals(me, this->my_addr))
1006 {
1007 this->my_addr->destroy(this->my_addr);
1008 this->my_addr = me->clone(me);
1009 }
1010 if (!other->equals(other, this->other_addr))
1011 {
1012 this->other_addr->destroy(this->other_addr);
1013 this->other_addr = other->clone(other);
1014 }
1015 }
1016
1017 this->encap = encap;
1018 set_state(this, old);
1019
1020 return SUCCESS;
1021 }
1022
1023 METHOD(child_sa_t, destroy, void,
1024 private_child_sa_t *this)
1025 {
1026 enumerator_t *enumerator;
1027 traffic_selector_t *my_ts, *other_ts;
1028 policy_priority_t priority;
1029
1030 priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
1031
1032 set_state(this, CHILD_DESTROYING);
1033
1034 /* delete SAs in the kernel, if they are set up */
1035 if (this->my_spi)
1036 {
1037 /* if CHILD was not established, use PROTO_ESP used during alloc_spi().
1038 * TODO: For AH support, we have to store protocol specific SPI.s */
1039 if (this->protocol == PROTO_NONE)
1040 {
1041 this->protocol = PROTO_ESP;
1042 }
1043 hydra->kernel_interface->del_sa(hydra->kernel_interface,
1044 this->other_addr, this->my_addr, this->my_spi,
1045 proto_ike2ip(this->protocol), this->my_cpi,
1046 this->mark_in);
1047 }
1048 if (this->other_spi)
1049 {
1050 hydra->kernel_interface->del_sa(hydra->kernel_interface,
1051 this->my_addr, this->other_addr, this->other_spi,
1052 proto_ike2ip(this->protocol), this->other_cpi,
1053 this->mark_out);
1054 }
1055
1056 if (this->config->install_policy(this->config))
1057 {
1058 /* delete all policies in the kernel */
1059 enumerator = create_policy_enumerator(this);
1060 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1061 {
1062 del_policies_internal(this, my_ts, other_ts, priority);
1063 if (priority == POLICY_PRIORITY_DEFAULT)
1064 {
1065 del_policies_internal(this, my_ts, other_ts,
1066 POLICY_PRIORITY_FALLBACK);
1067 }
1068 }
1069 enumerator->destroy(enumerator);
1070 }
1071
1072 this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
1073 this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
1074 this->my_addr->destroy(this->my_addr);
1075 this->other_addr->destroy(this->other_addr);
1076 DESTROY_IF(this->proposal);
1077 this->config->destroy(this->config);
1078 free(this);
1079 }
1080
1081 /**
1082 * Described in header.
1083 */
1084 child_sa_t * child_sa_create(host_t *me, host_t* other,
1085 child_cfg_t *config, u_int32_t rekey, bool encap)
1086 {
1087 static refcount_t reqid = 0;
1088 private_child_sa_t *this;
1089
1090 INIT(this,
1091 .public = {
1092 .get_name = _get_name,
1093 .get_reqid = _get_reqid,
1094 .get_config = _get_config,
1095 .get_state = _get_state,
1096 .set_state = _set_state,
1097 .get_spi = _get_spi,
1098 .get_cpi = _get_cpi,
1099 .get_protocol = _get_protocol,
1100 .set_protocol = _set_protocol,
1101 .get_mode = _get_mode,
1102 .set_mode = _set_mode,
1103 .get_proposal = _get_proposal,
1104 .set_proposal = _set_proposal,
1105 .get_lifetime = _get_lifetime,
1106 .get_usestats = _get_usestats,
1107 .get_mark = _get_mark,
1108 .has_encap = _has_encap,
1109 .get_ipcomp = _get_ipcomp,
1110 .set_ipcomp = _set_ipcomp,
1111 .get_close_action = _get_close_action,
1112 .set_close_action = _set_close_action,
1113 .get_dpd_action = _get_dpd_action,
1114 .set_dpd_action = _set_dpd_action,
1115 .alloc_spi = _alloc_spi,
1116 .alloc_cpi = _alloc_cpi,
1117 .install = _install,
1118 .update = _update,
1119 .add_policies = _add_policies,
1120 .get_traffic_selectors = _get_traffic_selectors,
1121 .create_policy_enumerator = _create_policy_enumerator,
1122 .destroy = _destroy,
1123 },
1124 .my_addr = me->clone(me),
1125 .other_addr = other->clone(other),
1126 .encap = encap,
1127 .ipcomp = IPCOMP_NONE,
1128 .state = CHILD_CREATED,
1129 .my_ts = linked_list_create(),
1130 .other_ts = linked_list_create(),
1131 .protocol = PROTO_NONE,
1132 .mode = MODE_TUNNEL,
1133 .close_action = config->get_close_action(config),
1134 .dpd_action = config->get_dpd_action(config),
1135 .reqid = config->get_reqid(config),
1136 .mark_in = config->get_mark(config, TRUE),
1137 .mark_out = config->get_mark(config, FALSE),
1138 );
1139
1140 this->config = config;
1141 config->get_ref(config);
1142
1143 if (!this->reqid)
1144 {
1145 /* reuse old reqid if we are rekeying an existing CHILD_SA */
1146 if (rekey)
1147 {
1148 this->reqid = rekey;
1149 }
1150 else
1151 {
1152 this->reqid = charon->traps->find_reqid(charon->traps, config);
1153 if (!this->reqid)
1154 {
1155 this->reqid = ref_get(&reqid);
1156 }
1157 }
1158 }
1159
1160 if (this->mark_in.value == MARK_REQID)
1161 {
1162 this->mark_in.value = this->reqid;
1163 }
1164 if (this->mark_out.value == MARK_REQID)
1165 {
1166 this->mark_out.value = this->reqid;
1167 }
1168
1169 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1170 if (config->get_mode(config) == MODE_TRANSPORT &&
1171 config->use_proxy_mode(config))
1172 {
1173 ts_type_t type;
1174 int family;
1175 chunk_t addr;
1176 host_t *host;
1177 enumerator_t *enumerator;
1178 linked_list_t *my_ts_list, *other_ts_list, *list;
1179 traffic_selector_t *my_ts, *other_ts;
1180
1181 this->mode = MODE_TRANSPORT;
1182
1183 list = linked_list_create_with_items(me, NULL);
1184 my_ts_list = config->get_traffic_selectors(config, TRUE, NULL, list);
1185 list->destroy(list);
1186 enumerator = my_ts_list->create_enumerator(my_ts_list);
1187 if (enumerator->enumerate(enumerator, &my_ts))
1188 {
1189 if (my_ts->is_host(my_ts, NULL) &&
1190 !my_ts->is_host(my_ts, this->my_addr))
1191 {
1192 type = my_ts->get_type(my_ts);
1193 family = (type == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
1194 addr = my_ts->get_from_address(my_ts);
1195 host = host_create_from_chunk(family, addr, 0);
1196 free(addr.ptr);
1197 DBG1(DBG_CHD, "my address: %H is a transport mode proxy for %H",
1198 this->my_addr, host);
1199 this->my_addr->destroy(this->my_addr);
1200 this->my_addr = host;
1201 }
1202 }
1203 enumerator->destroy(enumerator);
1204 my_ts_list->destroy_offset(my_ts_list, offsetof(traffic_selector_t, destroy));
1205
1206 list = linked_list_create_with_items(other, NULL);
1207 other_ts_list = config->get_traffic_selectors(config, FALSE, NULL, list);
1208 list->destroy(list);
1209 enumerator = other_ts_list->create_enumerator(other_ts_list);
1210 if (enumerator->enumerate(enumerator, &other_ts))
1211 {
1212 if (other_ts->is_host(other_ts, NULL) &&
1213 !other_ts->is_host(other_ts, this->other_addr))
1214 {
1215 type = other_ts->get_type(other_ts);
1216 family = (type == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
1217 addr = other_ts->get_from_address(other_ts);
1218 host = host_create_from_chunk(family, addr, 0);
1219 free(addr.ptr);
1220 DBG1(DBG_CHD, "other address: %H is a transport mode proxy for %H",
1221 this->other_addr, host);
1222 this->other_addr->destroy(this->other_addr);
1223 this->other_addr = host;
1224 }
1225 }
1226 enumerator->destroy(enumerator);
1227 other_ts_list->destroy_offset(other_ts_list, offsetof(traffic_selector_t, destroy));
1228 }
1229
1230 return &this->public;
1231 }