support for virtual IP definition on client side:
if leftsourceip is defined, it is requested. server may define rightsourceip=%config to accept any, or it may overwrite it using rightsourceip. if server does not return an IP, client enforces its configured leftsourceip.
This commit is contained in:
@@ -352,23 +352,31 @@ static dpd_action_t get_dpd_action(private_peer_cfg_t *this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of peer_cfg_t.get_virtual_ip.
|
* Implementation of peer_cfg_t.get_my_virtual_ip.
|
||||||
*/
|
*/
|
||||||
static host_t* get_virtual_ip(private_peer_cfg_t *this, host_t *suggestion)
|
static host_t* get_my_virtual_ip(private_peer_cfg_t *this)
|
||||||
{
|
{
|
||||||
if (suggestion == NULL)
|
if (this->my_virtual_ip == NULL)
|
||||||
{
|
{
|
||||||
if (this->my_virtual_ip)
|
|
||||||
{
|
|
||||||
return this->my_virtual_ip->clone(this->my_virtual_ip);
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (this->other_virtual_ip)
|
return this->my_virtual_ip->clone(this->my_virtual_ip);
|
||||||
{
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of peer_cfg_t.get_other_virtual_ip.
|
||||||
|
*/
|
||||||
|
static host_t* get_other_virtual_ip(private_peer_cfg_t *this, host_t *suggestion)
|
||||||
|
{
|
||||||
|
if (this->other_virtual_ip == NULL)
|
||||||
|
{ /* disallow */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!this->other_virtual_ip->is_anyaddr(this->other_virtual_ip))
|
||||||
|
{ /* force own configuration */
|
||||||
return this->other_virtual_ip->clone(this->other_virtual_ip);
|
return this->other_virtual_ip->clone(this->other_virtual_ip);
|
||||||
}
|
}
|
||||||
if (suggestion->is_anyaddr(suggestion))
|
if (suggestion == NULL || suggestion->is_anyaddr(suggestion))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -438,7 +446,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
|||||||
this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth;
|
this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth;
|
||||||
this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
|
this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
|
||||||
this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
|
this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
|
||||||
this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_virtual_ip;
|
this->public.get_my_virtual_ip = (host_t* (*) (peer_cfg_t *))get_my_virtual_ip;
|
||||||
|
this->public.get_other_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_other_virtual_ip;
|
||||||
this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
|
this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
|
||||||
this->public.destroy = (void(*)(peer_cfg_t *))destroy;
|
this->public.destroy = (void(*)(peer_cfg_t *))destroy;
|
||||||
|
|
||||||
|
|||||||
@@ -273,23 +273,30 @@ struct peer_cfg_t {
|
|||||||
dpd_action_t (*get_dpd_action) (peer_cfg_t *this);
|
dpd_action_t (*get_dpd_action) (peer_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a virtual IP for the local or the remote host.
|
* @brief Get a virtual IP for the local peer.
|
||||||
*
|
*
|
||||||
* By supplying NULL as IP, an IP for the local host is requested. It
|
* If no virtual IP should be used, NULL is returned. %any means to request
|
||||||
* may be %any or specific.
|
* a virtual IP using configuration payloads. A specific address is also
|
||||||
* By supplying %any as host, an IP from the pool is selected to be
|
* used for a request and may be changed by the server.
|
||||||
* served to the peer.
|
|
||||||
* If a specified host is supplied, it is checked if this address
|
|
||||||
* is acceptable to serve to the peer. If so, it is returned. Otherwise,
|
|
||||||
* an alternative IP is returned.
|
|
||||||
* In any mode, this call may return NULL indicating virtual IP should
|
|
||||||
* not be used.
|
|
||||||
*
|
*
|
||||||
* @param this peer_cfg
|
* @param this peer_cfg
|
||||||
* @param suggestion NULL, %any or specific, see description
|
* @param suggestion NULL, %any or specific
|
||||||
* @return clone of an IP to use, or NULL
|
* @return clone of an IP, %any or NULL
|
||||||
*/
|
*/
|
||||||
host_t* (*get_virtual_ip) (peer_cfg_t *this, host_t *suggestion);
|
host_t* (*get_my_virtual_ip) (peer_cfg_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a virtual IP for the remote peer.
|
||||||
|
*
|
||||||
|
* An IP may be supplied, if one was requested by the initiator. However,
|
||||||
|
* the suggestion is not more as it says, any address may be returned, even
|
||||||
|
* NULL to not use virtual IPs.
|
||||||
|
*
|
||||||
|
* @param this peer_cfg
|
||||||
|
* @param suggestion NULL, %any or specific
|
||||||
|
* @return clone of an IP to use
|
||||||
|
*/
|
||||||
|
host_t* (*get_other_virtual_ip) (peer_cfg_t *this, host_t *suggestion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a new reference.
|
* @brief Get a new reference.
|
||||||
|
|||||||
@@ -338,7 +338,10 @@ static void stroke_add_conn(private_stroke_interface_t *this,
|
|||||||
{
|
{
|
||||||
my_vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
|
my_vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
|
||||||
}
|
}
|
||||||
other_vip = host_create_from_string(msg->add_conn.other.sourceip, 0);
|
if (msg->add_conn.other.virtual_ip)
|
||||||
|
{
|
||||||
|
other_vip = host_create_from_string(msg->add_conn.other.sourceip, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (msg->add_conn.me.tohost)
|
if (msg->add_conn.me.tohost)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -266,6 +266,8 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||||||
|
|
||||||
if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
|
if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
|
||||||
{
|
{
|
||||||
|
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
|
||||||
|
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
|
||||||
SIG(CHILD_UP_FAILED, "no acceptable traffic selectors found");
|
SIG(CHILD_UP_FAILED, "no acceptable traffic selectors found");
|
||||||
return NOT_FOUND;
|
return NOT_FOUND;
|
||||||
}
|
}
|
||||||
@@ -524,7 +526,7 @@ static status_t build_i(private_child_create_t *this, message_t *message)
|
|||||||
me = this->ike_sa->get_my_host(this->ike_sa);
|
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||||
other = this->ike_sa->get_other_host(this->ike_sa);
|
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||||
vip = peer_cfg->get_virtual_ip(peer_cfg, NULL);
|
vip = peer_cfg->get_my_virtual_ip(peer_cfg);
|
||||||
|
|
||||||
if (vip)
|
if (vip)
|
||||||
{ /* propose a 0.0.0.0/0 subnet when we use virtual ip */
|
{ /* propose a 0.0.0.0/0 subnet when we use virtual ip */
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||||
this->virtual_ip = config->get_virtual_ip(config, NULL);
|
this->virtual_ip = config->get_my_virtual_ip(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_payloads(this, message, CFG_REQUEST);
|
build_payloads(this, message, CFG_REQUEST);
|
||||||
@@ -310,7 +310,7 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
|
|||||||
host_t *ip;
|
host_t *ip;
|
||||||
|
|
||||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
||||||
ip = config->get_virtual_ip(config, this->virtual_ip);
|
ip = config->get_other_virtual_ip(config, this->virtual_ip);
|
||||||
if (ip == NULL || ip->is_anyaddr(ip))
|
if (ip == NULL || ip->is_anyaddr(ip))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "not assigning a virtual IP to peer");
|
DBG1(DBG_IKE, "not assigning a virtual IP to peer");
|
||||||
@@ -349,13 +349,20 @@ static status_t process_i(private_ike_config_t *this, message_t *message)
|
|||||||
!message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
|
!message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
|
||||||
{
|
{
|
||||||
host_t *ip;
|
host_t *ip;
|
||||||
|
peer_cfg_t *config;
|
||||||
|
|
||||||
DESTROY_IF(this->virtual_ip);
|
DESTROY_IF(this->virtual_ip);
|
||||||
this->virtual_ip = NULL;
|
this->virtual_ip = NULL;
|
||||||
|
|
||||||
process_payloads(this, message);
|
process_payloads(this, message);
|
||||||
|
|
||||||
if (this->virtual_ip)
|
if (this->virtual_ip == NULL)
|
||||||
|
{ /* force a configured virtual IP, even server didn't return one */
|
||||||
|
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||||
|
this->virtual_ip = config->get_my_virtual_ip(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->virtual_ip && !this->virtual_ip->is_anyaddr(this->virtual_ip))
|
||||||
{
|
{
|
||||||
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
|
|||||||
msg_end->tohost = !conn_end->has_client;
|
msg_end->tohost = !conn_end->has_client;
|
||||||
msg_end->protocol = conn_end->protocol;
|
msg_end->protocol = conn_end->protocol;
|
||||||
msg_end->port = conn_end->port;
|
msg_end->port = conn_end->port;
|
||||||
msg_end->virtual_ip = conn_end->modecfg;
|
msg_end->virtual_ip = conn_end->modecfg || conn_end->has_srcip;
|
||||||
ip_address2string(&conn_end->srcip, buffer, sizeof(buffer));
|
ip_address2string(&conn_end->srcip, buffer, sizeof(buffer));
|
||||||
msg_end->sourceip = push_string(msg, buffer);
|
msg_end->sourceip = push_string(msg, buffer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user