nm_vpn_service_plugin_failure(plugin, failure);
}
-/**
- * Implementation of listener_t.ike_state_change
- */
-static bool ike_state_change(listener_t *listener, ike_sa_t *ike_sa,
- ike_sa_state_t state)
+METHOD(listener_t, ike_state_change, bool,
+ NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
- NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener;
-
- if (private->ike_sa == ike_sa && state == IKE_DESTROYING)
+ if (this->ike_sa == ike_sa && state == IKE_DESTROYING)
{
- signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
+ signal_failure(this->plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
return FALSE;
}
return TRUE;
}
-/**
- * Implementation of listener_t.child_state_change
- */
-static bool child_state_change(listener_t *listener, ike_sa_t *ike_sa,
- child_sa_t *child_sa, child_sa_state_t state)
+METHOD(listener_t, child_state_change, bool,
+ NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ child_sa_state_t state)
{
- NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener;
-
- if (private->ike_sa == ike_sa && state == CHILD_DESTROYING)
+ if (this->ike_sa == ike_sa && state == CHILD_DESTROYING)
{
- signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+ signal_failure(this->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
return FALSE;
}
return TRUE;
}
-/**
- * Implementation of listener_t.child_updown
- */
-static bool child_updown(listener_t *listener, ike_sa_t *ike_sa,
- child_sa_t *child_sa, bool up)
+METHOD(listener_t, ike_rekey, bool,
+ NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new)
{
- NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener;
+ if (this->ike_sa == old)
+ { /* follow a rekeyed IKE_SA */
+ this->ike_sa = new;
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_reestablish_pre, bool,
+ NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new)
+{
+ if (this->ike_sa == old)
+ { /* ignore child state changes during redirects etc. (task migration) */
+ this->listener.child_state_change = NULL;
+ }
+ return TRUE;
+}
- if (private->ike_sa == ike_sa)
+METHOD(listener_t, ike_reestablish_post, bool,
+ NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new,
+ bool initiated)
+{
+ if (this->ike_sa == old && initiated)
+ { /* if we get redirected during IKE_AUTH we just migrate to the new SA */
+ this->ike_sa = new;
+ /* re-register hooks to detect initiation failures */
+ this->listener.ike_state_change = _ike_state_change;
+ this->listener.child_state_change = _child_state_change;
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, child_updown, bool,
+ NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ bool up)
+{
+ if (this->ike_sa == ike_sa)
{
if (up)
{ /* disable initiate-failure-detection hooks */
- private->listener.ike_state_change = NULL;
- private->listener.child_state_change = NULL;
- signal_ip_config(private->plugin, ike_sa, child_sa);
+ this->listener.ike_state_change = NULL;
+ this->listener.child_state_change = NULL;
+ signal_ip_config(this->plugin, ike_sa, child_sa);
}
else
{
- signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+ if (ike_sa->has_condition(ike_sa, COND_REAUTHENTICATING))
+ { /* we ignore this during reauthentication */
+ return TRUE;
+ }
+ signal_failure(this->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
return FALSE;
}
}
return TRUE;
}
-/**
- * Implementation of listener_t.ike_rekey
- */
-static bool ike_rekey(listener_t *listener, ike_sa_t *old, ike_sa_t *new)
-{
- NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener;
-
- if (private->ike_sa == old)
- { /* follow a rekeyed IKE_SA */
- private->ike_sa = new;
- }
- return TRUE;
-}
-
/**
* Find a certificate for which we have a private key on a smartcard
*/
* Register listener, enable initiate-failure-detection hooks
*/
priv->ike_sa = ike_sa;
- priv->listener.ike_state_change = ike_state_change;
- priv->listener.child_state_change = child_state_change;
+ priv->listener.ike_state_change = _ike_state_change;
+ priv->listener.child_state_change = _child_state_change;
charon->bus->add_listener(charon->bus, &priv->listener);
/**
priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
priv->plugin = NM_VPN_SERVICE_PLUGIN(plugin);
memset(&priv->listener, 0, sizeof(listener_t));
- priv->listener.child_updown = child_updown;
- priv->listener.ike_rekey = ike_rekey;
+ priv->listener.child_updown = _child_updown;
+ priv->listener.ike_rekey = _ike_rekey;
+ priv->listener.ike_reestablish_pre = _ike_reestablish_pre;
+ priv->listener.ike_reestablish_post = _ike_reestablish_post;
priv->name = NULL;
}