redirect-job: Add job to redirect an active IKE_SA
[strongswan.git] / src / libcharon / processing / jobs / redirect_job.c
1 /*
2 * Copyright (C) 2015 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <daemon.h>
17
18 #include "redirect_job.h"
19
20 typedef struct private_redirect_job_t private_redirect_job_t;
21
22 /**
23 * Private data
24 */
25 struct private_redirect_job_t {
26
27 /**
28 * Public interface
29 */
30 redirect_job_t public;
31
32 /**
33 * ID of the IKE_SA to redirect
34 */
35 ike_sa_id_t *ike_sa_id;
36
37 /**
38 * Target gateway identity
39 */
40 identification_t *gateway;
41 };
42
43
44 METHOD(job_t, destroy, void,
45 private_redirect_job_t *this)
46 {
47 this->ike_sa_id->destroy(this->ike_sa_id);
48 this->gateway->destroy(this->gateway);
49 free(this);
50 }
51
52 METHOD(job_t, execute, job_requeue_t,
53 private_redirect_job_t *this)
54 {
55 ike_sa_t *ike_sa;
56
57 ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
58 this->ike_sa_id);
59 if (ike_sa)
60 {
61 if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
62 {
63 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
64 return JOB_REQUEUE_NONE;
65 }
66 if (ike_sa->redirect(ike_sa, this->gateway) == DESTROY_ME)
67 {
68 charon->ike_sa_manager->checkin_and_destroy(
69 charon->ike_sa_manager, ike_sa);
70 }
71 else
72 {
73 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
74 }
75 }
76 return JOB_REQUEUE_NONE;
77 }
78
79 METHOD(job_t, get_priority, job_priority_t,
80 private_redirect_job_t *this)
81 {
82 return JOB_PRIO_MEDIUM;
83 }
84
85 /*
86 * Described in header
87 */
88 redirect_job_t *redirect_job_create(ike_sa_id_t *ike_sa_id,
89 identification_t *gateway)
90 {
91 private_redirect_job_t *this;
92
93 INIT(this,
94 .public = {
95 .job_interface = {
96 .execute = _execute,
97 .get_priority = _get_priority,
98 .destroy = _destroy,
99 },
100 },
101 .ike_sa_id = ike_sa_id->clone(ike_sa_id),
102 .gateway = gateway->clone(gateway),
103 );
104
105 return &(this->public);
106 }