2 * Copyright (C) 2007 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
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>.
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
16 #include "mediation_job.h"
18 #include <encoding/payloads/endpoint_notify.h>
22 typedef struct private_mediation_job_t private_mediation_job_t
;
25 * Private data of an mediation_job_t Object
27 struct private_mediation_job_t
{
29 * public mediation_job_t interface
31 mediation_job_t
public;
36 identification_t
*target
;
39 * ID of the source peer.
41 identification_t
*source
;
56 linked_list_t
*endpoints
;
59 * Is this a callback job?
70 * Implements job_t.destroy.
72 static void destroy(private_mediation_job_t
*this)
74 DESTROY_IF(this->target
);
75 DESTROY_IF(this->source
);
76 chunk_free(&this->connect_id
);
77 chunk_free(&this->connect_key
);
78 DESTROY_OFFSET_IF(this->endpoints
, offsetof(endpoint_notify_t
, destroy
));
83 * Implementation of job_t.execute.
85 static void execute(private_mediation_job_t
*this)
87 ike_sa_id_t
*target_sa_id
;
89 target_sa_id
= charon
->mediation_manager
->check(charon
->mediation_manager
, this->target
);
93 ike_sa_t
*target_sa
= charon
->ike_sa_manager
->checkout(charon
->ike_sa_manager
,
99 /* send callback to a peer */
100 if (target_sa
->callback(target_sa
, this->source
) != SUCCESS
)
102 DBG1(DBG_JOB
, "callback for '%Y' to '%Y' failed",
103 this->source
, this->target
);
104 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, target_sa
);
111 /* normal mediation between two peers */
112 if (target_sa
->relay(target_sa
, this->source
, this->connect_id
,
113 this->connect_key
, this->endpoints
, this->response
) != SUCCESS
)
115 DBG1(DBG_JOB
, "mediation between '%Y' and '%Y' failed",
116 this->source
, this->target
);
117 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, target_sa
);
118 /* FIXME: notify the initiator */
124 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, target_sa
);
128 DBG1(DBG_JOB
, "mediation between '%Y' and '%Y' failed: "
129 "SA not found", this->source
, this->target
);
134 DBG1(DBG_JOB
, "mediation between '%Y' and '%Y' failed: "
135 "peer is not online anymore", this->source
, this->target
);
141 * Implementation of job_t.get_priority.
143 static job_priority_t
get_priority(private_mediation_job_t
*this)
145 return JOB_PRIO_MEDIUM
;
149 * Creates an empty mediation job
151 static private_mediation_job_t
*mediation_job_create_empty()
153 private_mediation_job_t
*this = malloc_thing(private_mediation_job_t
);
155 /* interface functions */
156 this->public.job_interface
.execute
= (void (*) (job_t
*)) execute
;
157 this->public.job_interface
.get_priority
= (job_priority_t (*) (job_t
*)) get_priority
;
158 this->public.job_interface
.destroy
= (void (*) (job_t
*)) destroy
;
160 /* private variables */
163 this->callback
= FALSE
;
164 this->connect_id
= chunk_empty
;
165 this->connect_key
= chunk_empty
;
166 this->endpoints
= NULL
;
167 this->response
= FALSE
;
173 * Described in header
175 mediation_job_t
*mediation_job_create(identification_t
*peer_id
,
176 identification_t
*requester
, chunk_t connect_id
, chunk_t connect_key
,
177 linked_list_t
*endpoints
, bool response
)
179 private_mediation_job_t
*this = mediation_job_create_empty();
181 this->target
= peer_id
->clone(peer_id
);
182 this->source
= requester
->clone(requester
);
183 this->connect_id
= chunk_clone(connect_id
);
184 this->connect_key
= chunk_clone(connect_key
);
185 this->endpoints
= endpoints
->clone_offset(endpoints
, offsetof(endpoint_notify_t
, clone
));
186 this->response
= response
;
188 return &this->public;
192 * Described in header
194 mediation_job_t
*mediation_callback_job_create(identification_t
*requester
,
195 identification_t
*peer_id
)
197 private_mediation_job_t
*this = mediation_job_create_empty();
199 this->target
= requester
->clone(requester
);
200 this->source
= peer_id
->clone(peer_id
);
201 this->callback
= TRUE
;
203 return &this->public;