{
DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config);
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- NULL, NULL);
+ NULL, NULL, 0);
}
else
{
if (id)
{
DBG1(DBG_CFG, "closing IKE_SA '%s'", config);
- charon->controller->terminate_ike(charon->controller, id, NULL, NULL);
+ charon->controller->terminate_ike(charon->controller, id, NULL, NULL, 0);
}
else
{
if (id)
{
DBG1(DBG_CFG, "closing CHILD_SA '%s'", config);
- charon->controller->terminate_child(charon->controller, id, NULL, NULL);
+ charon->controller->terminate_child(charon->controller, id,
+ NULL, NULL, 0);
}
else
{
entry_destroy(data->entry);
}
-METHOD(bus_t, listen_, void,
- private_bus_t *this, listener_t *listener, job_t *job)
+METHOD(bus_t, listen_, bool,
+ private_bus_t *this, listener_t *listener, job_t *job, u_int timeout)
{
- bool old;
+ bool old, timed_out = FALSE;
cleanup_data_t data;
+ timeval_t tv, add;
+
+ if (timeout)
+ {
+ add.tv_sec = timeout / 1000;
+ add.tv_usec = (timeout - (add.tv_sec * 1000)) * 1000;
+ time_monotonic(&tv);
+ timeradd(&tv, &add, &tv);
+ }
data.this = this;
data.entry = entry_create(listener, TRUE);
old = thread_cancelability(TRUE);
while (data.entry->blocker)
{
- data.entry->condvar->wait(data.entry->condvar, this->mutex);
+ if (timeout)
+ {
+ if (data.entry->condvar->timed_wait_abs(data.entry->condvar,
+ this->mutex, tv))
+ {
+ timed_out = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ data.entry->condvar->wait(data.entry->condvar, this->mutex);
+ }
}
thread_cancelability(old);
thread_cleanup_pop(FALSE);
/* unlock mutex */
thread_cleanup_pop(TRUE);
entry_destroy(data.entry);
+ return timed_out;
}
METHOD(bus_t, set_sa, void,
*
* @param listener listener to register
* @param job job to execute asynchronously when registered, or NULL
+ * @param timeout max timeout in ms to listen for events, 0 to disable
+ * @return TRUE if timed out
*/
- void (*listen)(bus_t *this, listener_t *listener, job_t *job);
+ bool (*listen)(bus_t *this, listener_t *listener, job_t *job, u_int timeout);
/**
* Set the IKE_SA the calling thread is using.
METHOD(controller_t, initiate, status_t,
private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- controller_cb_t callback, void *param)
+ controller_cb_t callback, void *param, u_int timeout)
{
interface_job_t job = {
.listener = {
}
else
{
- charon->bus->listen(charon->bus, &job.listener.public, &job.public);
+ if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+ timeout))
+ {
+ job.listener.status = OUT_OF_RES;
+ }
}
return job.listener.status;
}
METHOD(controller_t, terminate_ike, status_t,
controller_t *this, u_int32_t unique_id,
- controller_cb_t callback, void *param)
+ controller_cb_t callback, void *param, u_int timeout)
{
ike_sa_t *ike_sa;
interface_job_t job = {
}
else
{
- charon->bus->listen(charon->bus, &job.listener.public, &job.public);
+ if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+ timeout))
+ {
+ job.listener.status = OUT_OF_RES;
+ }
/* checkin of the ike_sa happened in the thread that executed the job */
charon->bus->set_sa(charon->bus, NULL);
}
}
METHOD(controller_t, terminate_child, status_t,
- controller_t *this, u_int32_t reqid, controller_cb_t callback, void *param)
+ controller_t *this, u_int32_t reqid,
+ controller_cb_t callback, void *param, u_int timeout)
{
ike_sa_t *ike_sa;
child_sa_t *child_sa;
}
else
{
- charon->bus->listen(charon->bus, &job.listener.public, &job.public);
+ if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+ timeout))
+ {
+ job.listener.status = OUT_OF_RES;
+ }
/* checkin of the ike_sa happened in the thread that executed the job */
charon->bus->set_sa(charon->bus, NULL);
}
* @param child_cfg child_cfg to set up CHILD_SA from
* @param cb logging callback
* @param param parameter to include in each call of cb
+ * @param timeout timeout in ms to wait for callbacks, 0 to disable
* @return
* - SUCCESS, if CHILD_SA established
* - FAILED, if setup failed
* - NEED_MORE, if callback returned FALSE
+ * - OUT_OF_RES if timed out
*/
status_t (*initiate)(controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- controller_cb_t callback, void *param);
+ controller_cb_t callback, void *param, u_int timeout);
/**
* Terminate an IKE_SA and all of its CHILD_SAs.
* @param unique_id unique id of the IKE_SA to terminate.
* @param cb logging callback
* @param param parameter to include in each call of cb
+ * @param timeout timeout in ms to wait for callbacks, 0 to disable
* @return
* - SUCCESS, if CHILD_SA terminated
* - NOT_FOUND, if no such CHILD_SA found
* - NEED_MORE, if callback returned FALSE
+ * - OUT_OF_RES if timed out
*/
status_t (*terminate_ike)(controller_t *this, u_int32_t unique_id,
- controller_cb_t callback, void *param);
+ controller_cb_t callback, void *param,
+ u_int timeout);
/**
* Terminate a CHILD_SA.
* @param reqid reqid of the CHILD_SA to terminate
* @param cb logging callback
* @param param parameter to include in each call of cb
+ * @param timeout timeout in ms to wait for callbacks, 0 to disable
* @return
* - SUCCESS, if CHILD_SA terminated
* - NOT_FOUND, if no such CHILD_SA found
* - NEED_MORE, if callback returned FALSE
+ * - OUT_OF_RES if timed out
*/
status_t (*terminate_child)(controller_t *this, u_int32_t reqid,
- controller_cb_t callback, void *param);
+ controller_cb_t callback, void *param,
+ u_int timeout);
/**
* Destroy a controller_t instance.
charon->controller->initiate(charon->controller,
peer_cfg, child_cfg->get_ref(child_cfg),
- NULL, NULL);
+ NULL, NULL, 0);
if (s)
{
sleep(s);
id = ike_sa->get_unique_id(ike_sa);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
charon->controller->terminate_ike(charon->controller, id,
- NULL, NULL);
+ NULL, NULL, 0);
}
this->current = (g_free(this->current), NULL);
this->status = VPN_STATUS_DISCONNECTED;
peer_cfg->get_ref(peer_cfg);
enumerator->destroy(enumerator);
charon->controller->initiate(charon->controller,
- peer_cfg, child_cfg, NULL, NULL);
+ peer_cfg, child_cfg, NULL, NULL, 0);
}
else
{
id = ike_sa->get_unique_id(ike_sa);
enumerator->destroy(enumerator);
charon->controller->terminate_ike(charon->controller, id,
- controller_cb_empty, NULL);
+ controller_cb_empty, NULL, 0);
return TRUE;
}
}
if (ike)
{
status = charon->controller->terminate_ike(
- charon->controller, id,
- (controller_cb_t)xml_callback, writer);
+ charon->controller, id,
+ (controller_cb_t)xml_callback, writer, 0);
}
else
{
status = charon->controller->terminate_child(
- charon->controller, id,
- (controller_cb_t)xml_callback, writer);
+ charon->controller, id,
+ (controller_cb_t)xml_callback, writer, 0);
}
/* </log> */
xmlTextWriterEndElement(writer);
{
status = charon->controller->initiate(charon->controller,
peer, child, (controller_cb_t)xml_callback,
- writer);
+ writer, 0);
}
else
{
if (msg->output_verbosity < 0)
{
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- NULL, NULL);
+ NULL, NULL, 0);
}
else
{
stroke_log_info_t info = { msg->output_verbosity, out };
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
}
if (child)
{
charon->controller->terminate_child(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
else
{
charon->controller->terminate_ike(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
return;
}
while (enumerator->enumerate(enumerator, &del))
{
charon->controller->terminate_child(charon->controller, del,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
enumerator->destroy(enumerator);
while (enumerator->enumerate(enumerator, &del))
{
charon->controller->terminate_ike(charon->controller, del,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
enumerator->destroy(enumerator);
while (enumerator->enumerate(enumerator, &del))
{
charon->controller->terminate_ike(charon->controller, del,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
enumerator->destroy(enumerator);
list->destroy(list);
}
}
else
- {
+ {
if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
{
fprintf(out, "'%s' routed\n", name);
enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
if (enumerator->enumerate(enumerator, &child_cfg) &&
charon->controller->initiate(charon->controller, peer_cfg,
- child_cfg->get_ref(child_cfg),
- controller_cb_empty, NULL) == SUCCESS)
+ child_cfg->get_ref(child_cfg),
+ controller_cb_empty, NULL, 0) == SUCCESS)
{
write_fifo(this, "connection '%s' established\n", name);
}
id = ike_sa->get_unique_id(ike_sa);
enumerator->destroy(enumerator);
charon->controller->terminate_ike(charon->controller, id,
- controller_cb_empty, NULL);
+ controller_cb_empty, NULL, 0);
write_fifo(this, "connection '%s' terminated\n", name);
return;
}
mediation_cfg->get_ref(mediation_cfg);
if (charon->controller->initiate(charon->controller, mediation_cfg,
- NULL, (controller_cb_t)initiate_callback, this) != SUCCESS)
+ NULL, (controller_cb_t)initiate_callback, this, 0) != SUCCESS)
{
mediation_cfg->destroy(mediation_cfg);
mediated_cfg->destroy(mediated_cfg);
charon->controller->initiate(charon->controller,
peer_cfg->get_ref(peer_cfg),
child_cfg->get_ref(child_cfg),
- NULL, NULL);
+ NULL, NULL, 0);
break;
case ACTION_ROUTE:
DBG1(DBG_JOB, "start action: route '%s'", name);