improved MOBIKE:
prefer address family already used do not change address implicit when mobike supported handle multiple simultaneous roaming requests more properly proper enabling/disabling of UDP encapsulation
This commit is contained in:
@@ -615,7 +615,8 @@ static void process_link(private_kernel_interface_t *this,
|
|||||||
/* send an update to all IKE_SAs */
|
/* send an update to all IKE_SAs */
|
||||||
if (update && event)
|
if (update && event)
|
||||||
{
|
{
|
||||||
charon->processor->queue_job(charon->processor, (job_t*)roam_job_create());
|
charon->processor->queue_job(charon->processor,
|
||||||
|
(job_t*)roam_job_create(TRUE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +634,7 @@ static void process_addr(private_kernel_interface_t *this,
|
|||||||
iface_entry_t *iface;
|
iface_entry_t *iface;
|
||||||
addr_entry_t *addr;
|
addr_entry_t *addr;
|
||||||
chunk_t local = chunk_empty, address = chunk_empty;
|
chunk_t local = chunk_empty, address = chunk_empty;
|
||||||
bool update = FALSE, found = FALSE;
|
bool update = FALSE, found = FALSE, changed = FALSE;
|
||||||
|
|
||||||
while(RTA_OK(rta, rtasize))
|
while(RTA_OK(rta, rtasize))
|
||||||
{
|
{
|
||||||
@@ -681,6 +682,7 @@ static void process_addr(private_kernel_interface_t *this,
|
|||||||
found = TRUE;
|
found = TRUE;
|
||||||
if (hdr->nlmsg_type == RTM_DELADDR)
|
if (hdr->nlmsg_type == RTM_DELADDR)
|
||||||
{
|
{
|
||||||
|
changed = TRUE;
|
||||||
addrs->remove(addrs);
|
addrs->remove(addrs);
|
||||||
addr_entry_destroy(addr);
|
addr_entry_destroy(addr);
|
||||||
DBG1(DBG_KNL, "%H disappeared from %s", host, iface->ifname);
|
DBG1(DBG_KNL, "%H disappeared from %s", host, iface->ifname);
|
||||||
@@ -694,6 +696,7 @@ static void process_addr(private_kernel_interface_t *this,
|
|||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
|
changed = TRUE;
|
||||||
addr = malloc_thing(addr_entry_t);
|
addr = malloc_thing(addr_entry_t);
|
||||||
addr->ip = host->clone(host);
|
addr->ip = host->clone(host);
|
||||||
addr->virtual = FALSE;
|
addr->virtual = FALSE;
|
||||||
@@ -718,9 +721,10 @@ static void process_addr(private_kernel_interface_t *this,
|
|||||||
host->destroy(host);
|
host->destroy(host);
|
||||||
|
|
||||||
/* send an update to all IKE_SAs */
|
/* send an update to all IKE_SAs */
|
||||||
if (update && event)
|
if (update && event && changed)
|
||||||
{
|
{
|
||||||
charon->processor->queue_job(charon->processor, (job_t*)roam_job_create());
|
charon->processor->queue_job(charon->processor,
|
||||||
|
(job_t*)roam_job_create(TRUE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +821,7 @@ static job_requeue_t receive_events(private_kernel_interface_t *this)
|
|||||||
case RTM_NEWROUTE:
|
case RTM_NEWROUTE:
|
||||||
case RTM_DELROUTE:
|
case RTM_DELROUTE:
|
||||||
charon->processor->queue_job(charon->processor,
|
charon->processor->queue_job(charon->processor,
|
||||||
(job_t*)roam_job_create());
|
(job_t*)roam_job_create(FALSE));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1763,11 +1767,11 @@ static status_t add_sa(private_kernel_interface_t *this,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct xfrm_encap_tmpl* encap = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
|
struct xfrm_encap_tmpl* tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
|
||||||
encap->encap_type = UDP_ENCAP_ESPINUDP;
|
tmpl->encap_type = UDP_ENCAP_ESPINUDP;
|
||||||
encap->encap_sport = htons(src->get_port(src));
|
tmpl->encap_sport = htons(src->get_port(src));
|
||||||
encap->encap_dport = htons(dst->get_port(dst));
|
tmpl->encap_dport = htons(dst->get_port(dst));
|
||||||
memset(&encap->encap_oa, 0, sizeof (xfrm_address_t));
|
memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t));
|
||||||
/* encap_oa could probably be derived from the
|
/* encap_oa could probably be derived from the
|
||||||
* traffic selectors [rfc4306, p39]. In the netlink kernel implementation
|
* traffic selectors [rfc4306, p39]. In the netlink kernel implementation
|
||||||
* pluto does the same as we do here but it uses encap_oa in the
|
* pluto does the same as we do here but it uses encap_oa in the
|
||||||
@@ -1794,13 +1798,16 @@ static status_t add_sa(private_kernel_interface_t *this,
|
|||||||
static status_t update_sa(private_kernel_interface_t *this,
|
static status_t update_sa(private_kernel_interface_t *this,
|
||||||
u_int32_t spi, protocol_id_t protocol,
|
u_int32_t spi, protocol_id_t protocol,
|
||||||
host_t *src, host_t *dst,
|
host_t *src, host_t *dst,
|
||||||
host_t *new_src, host_t *new_dst)
|
host_t *new_src, host_t *new_dst, bool encap)
|
||||||
{
|
{
|
||||||
unsigned char request[BUFFER_SIZE];
|
unsigned char request[BUFFER_SIZE], *pos;
|
||||||
struct nlmsghdr *hdr, *out = NULL;
|
struct nlmsghdr *hdr, *out = NULL;
|
||||||
struct xfrm_usersa_id *sa_id;
|
struct xfrm_usersa_id *sa_id;
|
||||||
struct xfrm_usersa_info *sa = NULL;
|
struct xfrm_usersa_info *out_sa = NULL, *sa;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
struct rtattr *rta;
|
||||||
|
size_t rtasize;
|
||||||
|
struct xfrm_encap_tmpl* tmpl = NULL;
|
||||||
|
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
|
|
||||||
@@ -1827,7 +1834,7 @@ static status_t update_sa(private_kernel_interface_t *this,
|
|||||||
{
|
{
|
||||||
case XFRM_MSG_NEWSA:
|
case XFRM_MSG_NEWSA:
|
||||||
{
|
{
|
||||||
sa = NLMSG_DATA(hdr);
|
out_sa = NLMSG_DATA(hdr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NLMSG_ERROR:
|
case NLMSG_ERROR:
|
||||||
@@ -1846,7 +1853,7 @@ static status_t update_sa(private_kernel_interface_t *this,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa == NULL ||
|
if (out_sa == NULL ||
|
||||||
this->public.del_sa(&this->public, dst, spi, protocol) != SUCCESS)
|
this->public.del_sa(&this->public, dst, spi, protocol) != SUCCESS)
|
||||||
{
|
{
|
||||||
DBG1(DBG_KNL, "unable to update SAD entry with SPI 0x%x", spi);
|
DBG1(DBG_KNL, "unable to update SAD entry with SPI 0x%x", spi);
|
||||||
@@ -1857,10 +1864,14 @@ static status_t update_sa(private_kernel_interface_t *this,
|
|||||||
DBG2(DBG_KNL, "updating SAD entry with SPI 0x%x from %#H..%#H to %#H..%#H",
|
DBG2(DBG_KNL, "updating SAD entry with SPI 0x%x from %#H..%#H to %#H..%#H",
|
||||||
spi, src, dst, new_src, new_dst);
|
spi, src, dst, new_src, new_dst);
|
||||||
|
|
||||||
/* update the values in the queried SA */
|
/* copy over the SA from out to request */
|
||||||
hdr = out;
|
hdr = (struct nlmsghdr*)request;
|
||||||
|
memcpy(hdr, out, min(out->nlmsg_len, sizeof(request)));
|
||||||
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||||
hdr->nlmsg_type = XFRM_MSG_NEWSA;
|
hdr->nlmsg_type = XFRM_MSG_NEWSA;
|
||||||
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
|
||||||
|
sa = NLMSG_DATA(hdr);
|
||||||
|
sa->family = new_dst->get_family(new_dst);
|
||||||
|
|
||||||
if (!src->ip_equals(src, new_src))
|
if (!src->ip_equals(src, new_src))
|
||||||
{
|
{
|
||||||
@@ -1871,24 +1882,39 @@ static status_t update_sa(private_kernel_interface_t *this,
|
|||||||
host2xfrm(new_dst, &sa->id.daddr);
|
host2xfrm(new_dst, &sa->id.daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->get_port(src) != new_src->get_port(new_src) ||
|
rta = XFRM_RTA(out, struct xfrm_usersa_info);
|
||||||
dst->get_port(dst) != new_dst->get_port(new_dst))
|
rtasize = XFRM_PAYLOAD(out, struct xfrm_usersa_info);
|
||||||
|
pos = (u_char*)XFRM_RTA(hdr, struct xfrm_usersa_info);
|
||||||
|
while(RTA_OK(rta, rtasize))
|
||||||
{
|
{
|
||||||
struct rtattr *rtattr = XFRM_RTA(hdr, struct xfrm_usersa_info);
|
/* copy all attributes, but not XFRMA_ENCAP if we are disabling it */
|
||||||
size_t rtsize = XFRM_PAYLOAD(hdr, struct xfrm_usersa_info);
|
if (rta->rta_type != XFRMA_ENCAP || encap)
|
||||||
while (RTA_OK(rtattr, rtsize))
|
|
||||||
{
|
{
|
||||||
if (rtattr->rta_type == XFRMA_ENCAP)
|
if (rta->rta_type == XFRMA_ENCAP)
|
||||||
{
|
{ /* update encap tmpl */
|
||||||
struct xfrm_encap_tmpl* encap;
|
tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta);
|
||||||
encap = (struct xfrm_encap_tmpl*)RTA_DATA(rtattr);
|
tmpl->encap_sport = ntohs(new_src->get_port(new_src));
|
||||||
encap->encap_sport = ntohs(new_src->get_port(new_src));
|
tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
|
||||||
encap->encap_dport = ntohs(new_dst->get_port(new_dst));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
rtattr = RTA_NEXT(rtattr, rtsize);
|
memcpy(pos, rta, rta->rta_len);
|
||||||
|
pos += rta->rta_len;
|
||||||
|
hdr->nlmsg_len += rta->rta_len;
|
||||||
}
|
}
|
||||||
|
rta = RTA_NEXT(rta, rtasize);
|
||||||
}
|
}
|
||||||
|
if (tmpl == NULL && encap)
|
||||||
|
{ /* add tmpl if we are enabling it */
|
||||||
|
rta = (struct rtattr*)pos;
|
||||||
|
rta->rta_type = XFRMA_ENCAP;
|
||||||
|
rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
|
||||||
|
hdr->nlmsg_len += rta->rta_len;
|
||||||
|
tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta);
|
||||||
|
tmpl->encap_type = UDP_ENCAP_ESPINUDP;
|
||||||
|
tmpl->encap_sport = ntohs(new_src->get_port(new_src));
|
||||||
|
tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
|
||||||
|
memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t));
|
||||||
|
}
|
||||||
|
|
||||||
if (netlink_send_ack(this, this->socket_xfrm, hdr) != SUCCESS)
|
if (netlink_send_ack(this, this->socket_xfrm, hdr) != SUCCESS)
|
||||||
{
|
{
|
||||||
DBG1(DBG_KNL, "unable to update SAD entry with SPI 0x%x", spi);
|
DBG1(DBG_KNL, "unable to update SAD entry with SPI 0x%x", spi);
|
||||||
@@ -2320,7 +2346,7 @@ kernel_interface_t *kernel_interface_create()
|
|||||||
/* public functions */
|
/* public functions */
|
||||||
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
|
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
|
||||||
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,mode_t,bool,bool))add_sa;
|
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,mode_t,bool,bool))add_sa;
|
||||||
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_t*,host_t*))update_sa;
|
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_t*,host_t*,bool))update_sa;
|
||||||
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
|
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
|
||||||
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
|
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
|
||||||
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t))add_policy;
|
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t))add_policy;
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ struct kernel_interface_t {
|
|||||||
* @param dst current destination address
|
* @param dst current destination address
|
||||||
* @param new_src new source address
|
* @param new_src new source address
|
||||||
* @param new_dst new destination address
|
* @param new_dst new destination address
|
||||||
|
* @param encap use UDP encapsulation
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS
|
* - SUCCESS
|
||||||
* - FAILED if kernel comm failed
|
* - FAILED if kernel comm failed
|
||||||
@@ -146,7 +147,7 @@ struct kernel_interface_t {
|
|||||||
status_t (*update_sa)(kernel_interface_t *this,
|
status_t (*update_sa)(kernel_interface_t *this,
|
||||||
u_int32_t spi, protocol_id_t protocol,
|
u_int32_t spi, protocol_id_t protocol,
|
||||||
host_t *src, host_t *dst,
|
host_t *src, host_t *dst,
|
||||||
host_t *new_src, host_t *new_dst);
|
host_t *new_src, host_t *new_dst, bool encap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Query the use time of an SA.
|
* @brief Query the use time of an SA.
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ struct private_roam_job_t {
|
|||||||
* public roam_job_t interface
|
* public roam_job_t interface
|
||||||
*/
|
*/
|
||||||
roam_job_t public;
|
roam_job_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* has the address list changed, or the routing only?
|
||||||
|
*/
|
||||||
|
bool address;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +80,7 @@ static void execute(private_roam_job_t *this)
|
|||||||
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
|
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
|
||||||
if (ike_sa)
|
if (ike_sa)
|
||||||
{
|
{
|
||||||
if (ike_sa->roam(ike_sa) == DESTROY_ME)
|
if (ike_sa->roam(ike_sa, this->address) == DESTROY_ME)
|
||||||
{
|
{
|
||||||
charon->ike_sa_manager->checkin_and_destroy(
|
charon->ike_sa_manager->checkin_and_destroy(
|
||||||
charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager, ike_sa);
|
||||||
@@ -95,7 +100,7 @@ static void execute(private_roam_job_t *this)
|
|||||||
/*
|
/*
|
||||||
* Described in header
|
* Described in header
|
||||||
*/
|
*/
|
||||||
roam_job_t *roam_job_create()
|
roam_job_t *roam_job_create(bool address)
|
||||||
{
|
{
|
||||||
private_roam_job_t *this = malloc_thing(private_roam_job_t);
|
private_roam_job_t *this = malloc_thing(private_roam_job_t);
|
||||||
|
|
||||||
@@ -103,6 +108,8 @@ roam_job_t *roam_job_create()
|
|||||||
this->public.job_interface.execute = (void (*) (job_t *)) execute;
|
this->public.job_interface.execute = (void (*) (job_t *)) execute;
|
||||||
this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
|
this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
|
||||||
|
|
||||||
|
this->address = address;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,11 +50,12 @@ struct roam_job_t {
|
|||||||
/**
|
/**
|
||||||
* @brief Creates a job to inform IKE_SAs about an updated address list.
|
* @brief Creates a job to inform IKE_SAs about an updated address list.
|
||||||
*
|
*
|
||||||
|
* @param address TRUE if address list changed, FALSE if routing changed
|
||||||
* @return initiate_ike_sa_job_t object
|
* @return initiate_ike_sa_job_t object
|
||||||
*
|
*
|
||||||
* @ingroup jobs
|
* @ingroup jobs
|
||||||
*/
|
*/
|
||||||
roam_job_t *roam_job_create();
|
roam_job_t *roam_job_create(bool address);
|
||||||
|
|
||||||
#endif /*ROAM_JOB_H_*/
|
#endif /*ROAM_JOB_H_*/
|
||||||
|
|
||||||
|
|||||||
@@ -776,20 +776,22 @@ static status_t update_hosts(private_child_sa_t *this,
|
|||||||
host_t *me, host_t *other, bool encap)
|
host_t *me, host_t *other, bool encap)
|
||||||
{
|
{
|
||||||
/* anything changed at all? */
|
/* anything changed at all? */
|
||||||
if (me->equals(me, this->me.addr) && other->equals(other, this->other.addr))
|
if (me->equals(me, this->me.addr) &&
|
||||||
|
other->equals(other, this->other.addr) && this->encap == encap)
|
||||||
{
|
{
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* run updown script to remove iptables rules */
|
/* run updown script to remove iptables rules */
|
||||||
updown(this, FALSE);
|
updown(this, FALSE);
|
||||||
|
|
||||||
|
this->encap = encap;
|
||||||
|
|
||||||
/* update our (initator) SAs */
|
/* update our (initator) SAs */
|
||||||
charon->kernel_interface->update_sa(charon->kernel_interface, this->me.spi,
|
charon->kernel_interface->update_sa(charon->kernel_interface, this->me.spi,
|
||||||
this->protocol, this->other.addr, this->me.addr, other, me);
|
this->protocol, this->other.addr, this->me.addr, other, me, encap);
|
||||||
/* update his (responder) SAs */
|
/* update his (responder) SAs */
|
||||||
charon->kernel_interface->update_sa(charon->kernel_interface, this->other.spi,
|
charon->kernel_interface->update_sa(charon->kernel_interface, this->other.spi,
|
||||||
this->protocol, this->me.addr, this->other.addr, me, other);
|
this->protocol, this->me.addr, this->other.addr, me, other, encap);
|
||||||
|
|
||||||
/* update policies */
|
/* update policies */
|
||||||
if (!me->ip_equals(me, this->me.addr) ||
|
if (!me->ip_equals(me, this->me.addr) ||
|
||||||
|
|||||||
+73
-9
@@ -220,6 +220,11 @@ struct private_ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *additional_addresses;
|
linked_list_t *additional_addresses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number pending UPDATE_SA_ADDRESS (MOBIKE)
|
||||||
|
*/
|
||||||
|
u_int32_t pending_updates;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timestamps for this IKE_SA
|
* Timestamps for this IKE_SA
|
||||||
*/
|
*/
|
||||||
@@ -716,6 +721,22 @@ static iterator_t* create_additional_address_iterator(private_ike_sa_t *this)
|
|||||||
this->additional_addresses, TRUE);
|
this->additional_addresses, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ike_sa_t.set_pending_updates.
|
||||||
|
*/
|
||||||
|
static void set_pending_updates(private_ike_sa_t *this, u_int32_t updates)
|
||||||
|
{
|
||||||
|
this->pending_updates = updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ike_sa_t.get_pending_updates.
|
||||||
|
*/
|
||||||
|
static u_int32_t get_pending_updates(private_ike_sa_t *this)
|
||||||
|
{
|
||||||
|
return this->pending_updates;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update hosts, as addresses may change (NAT)
|
* Update hosts, as addresses may change (NAT)
|
||||||
*/
|
*/
|
||||||
@@ -723,6 +744,11 @@ static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
|
|||||||
{
|
{
|
||||||
bool update = FALSE;
|
bool update = FALSE;
|
||||||
|
|
||||||
|
if (supports_extension(this, EXT_MOBIKE))
|
||||||
|
{ /* if peer speaks mobike, address updates are explicit only */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (me == NULL)
|
if (me == NULL)
|
||||||
{
|
{
|
||||||
me = this->my_host;
|
me = this->my_host;
|
||||||
@@ -1727,16 +1753,23 @@ static int get_path_prio(host_t *me, host_t *other)
|
|||||||
/**
|
/**
|
||||||
* Implementation of ike_sa_t.roam.
|
* Implementation of ike_sa_t.roam.
|
||||||
*/
|
*/
|
||||||
static status_t roam(private_ike_sa_t *this)
|
static status_t roam(private_ike_sa_t *this, bool address)
|
||||||
{
|
{
|
||||||
iterator_t *iterator;
|
iterator_t *iterator;
|
||||||
host_t *me, *other, *cand_me, *cand_other;
|
host_t *me, *other, *cand_me, *cand_other;
|
||||||
ike_mobike_t *mobike;
|
ike_mobike_t *mobike;
|
||||||
int prio, best = 0;
|
int prio, best4 = 0, best6 = 0;
|
||||||
|
|
||||||
/* only initiator handles address updated actively */
|
/* responder just updates the peer about changed address config */
|
||||||
if (!this->ike_sa_id->is_initiator(this->ike_sa_id))
|
if (!this->ike_sa_id->is_initiator(this->ike_sa_id))
|
||||||
{
|
{
|
||||||
|
if (supports_extension(this, EXT_MOBIKE) && address)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "sending address list update using MOBIKE");
|
||||||
|
mobike = ike_mobike_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
|
||||||
|
return this->task_manager->initiate(this->task_manager);
|
||||||
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1746,11 +1779,20 @@ static status_t roam(private_ike_sa_t *this)
|
|||||||
other);
|
other);
|
||||||
if (me)
|
if (me)
|
||||||
{
|
{
|
||||||
best = get_path_prio(me, other);
|
if (me->get_family(me) == AF_INET)
|
||||||
|
{
|
||||||
|
best4 = get_path_prio(me, other);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
best6 = get_path_prio(me, other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iterator = create_additional_address_iterator(this);
|
iterator = create_additional_address_iterator(this);
|
||||||
while (iterator->iterate(iterator, (void**)&cand_other))
|
while (iterator->iterate(iterator, (void**)&cand_other))
|
||||||
{
|
{
|
||||||
|
bool better = FALSE;
|
||||||
|
|
||||||
cand_me = charon->kernel_interface->get_source_addr(
|
cand_me = charon->kernel_interface->get_source_addr(
|
||||||
charon->kernel_interface, cand_other);
|
charon->kernel_interface, cand_other);
|
||||||
if (!cand_me)
|
if (!cand_me)
|
||||||
@@ -1763,10 +1805,28 @@ static status_t roam(private_ike_sa_t *this)
|
|||||||
cand_me->destroy(cand_me);
|
cand_me->destroy(cand_me);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
prio = get_path_prio(cand_me, cand_other);
|
prio = get_path_prio(cand_me, cand_other);
|
||||||
if (prio > best)
|
if (cand_me->get_family(cand_me) == AF_INET)
|
||||||
|
{
|
||||||
|
if (prio > best4 && (best6 == 0 ||
|
||||||
|
this->my_host->get_family(this->my_host) == AF_INET))
|
||||||
|
{
|
||||||
|
best4 = prio;
|
||||||
|
better = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prio > best6 && (best4 == 0 ||
|
||||||
|
this->my_host->get_family(this->my_host) == AF_INET6))
|
||||||
|
{
|
||||||
|
best6 = prio;
|
||||||
|
better = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (better)
|
||||||
{
|
{
|
||||||
best = prio;
|
|
||||||
DESTROY_IF(me);
|
DESTROY_IF(me);
|
||||||
me = cand_me;
|
me = cand_me;
|
||||||
other = cand_other;
|
other = cand_other;
|
||||||
@@ -1797,19 +1857,20 @@ static status_t roam(private_ike_sa_t *this)
|
|||||||
me->set_port(me, this->my_host->get_port(this->my_host));
|
me->set_port(me, this->my_host->get_port(this->my_host));
|
||||||
other = other->clone(other);
|
other = other->clone(other);
|
||||||
other->set_port(other, this->other_host->get_port(this->other_host));
|
other->set_port(other, this->other_host->get_port(this->other_host));
|
||||||
|
set_my_host(this, me);
|
||||||
|
set_other_host(this, other);
|
||||||
|
|
||||||
/* update addresses with mobike, if supported ... */
|
/* update addresses with mobike, if supported ... */
|
||||||
if (supports_extension(this, EXT_MOBIKE))
|
if (supports_extension(this, EXT_MOBIKE))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "requesting address change using MOBIKE");
|
DBG1(DBG_IKE, "requesting address change using MOBIKE");
|
||||||
mobike = ike_mobike_create(&this->public, TRUE);
|
mobike = ike_mobike_create(&this->public, TRUE);
|
||||||
mobike->roam(mobike, me, other);
|
mobike->roam(mobike, address);
|
||||||
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
|
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
|
||||||
return this->task_manager->initiate(this->task_manager);
|
return this->task_manager->initiate(this->task_manager);
|
||||||
}
|
}
|
||||||
DBG1(DBG_IKE, "reestablishing IKE_SA due address change");
|
DBG1(DBG_IKE, "reestablishing IKE_SA due address change");
|
||||||
/* ... reestablish if not */
|
/* ... reestablish if not */
|
||||||
set_my_host(this, me);
|
|
||||||
return reestablish(this);
|
return reestablish(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2078,6 +2139,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->public.supports_extension = (bool(*)(ike_sa_t*, ike_extension_t extension))supports_extension;
|
this->public.supports_extension = (bool(*)(ike_sa_t*, ike_extension_t extension))supports_extension;
|
||||||
this->public.set_condition = (void (*)(ike_sa_t*, ike_condition_t,bool)) set_condition;
|
this->public.set_condition = (void (*)(ike_sa_t*, ike_condition_t,bool)) set_condition;
|
||||||
this->public.has_condition = (bool (*)(ike_sa_t*,ike_condition_t)) has_condition;
|
this->public.has_condition = (bool (*)(ike_sa_t*,ike_condition_t)) has_condition;
|
||||||
|
this->public.set_pending_updates = (void(*)(ike_sa_t*, u_int32_t updates))set_pending_updates;
|
||||||
|
this->public.get_pending_updates = (u_int32_t(*)(ike_sa_t*))get_pending_updates;
|
||||||
this->public.create_additional_address_iterator = (iterator_t*(*)(ike_sa_t*))create_additional_address_iterator;
|
this->public.create_additional_address_iterator = (iterator_t*(*)(ike_sa_t*))create_additional_address_iterator;
|
||||||
this->public.add_additional_address = (void(*)(ike_sa_t*, host_t *host))add_additional_address;
|
this->public.add_additional_address = (void(*)(ike_sa_t*, host_t *host))add_additional_address;
|
||||||
this->public.retransmit = (status_t (*)(ike_sa_t *, u_int32_t)) retransmit;
|
this->public.retransmit = (status_t (*)(ike_sa_t *, u_int32_t)) retransmit;
|
||||||
@@ -2098,7 +2161,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
|
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
|
||||||
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
|
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
|
||||||
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
|
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
|
||||||
this->public.roam = (status_t(*)(ike_sa_t*))roam;
|
this->public.roam = (status_t(*)(ike_sa_t*,bool))roam;
|
||||||
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
|
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
|
||||||
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
|
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
|
||||||
this->public.reset = (void (*)(ike_sa_t*))reset;
|
this->public.reset = (void (*)(ike_sa_t*))reset;
|
||||||
@@ -2138,6 +2201,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->other_virtual_ip = NULL;
|
this->other_virtual_ip = NULL;
|
||||||
this->dns_servers = linked_list_create();
|
this->dns_servers = linked_list_create();
|
||||||
this->additional_addresses = linked_list_create();
|
this->additional_addresses = linked_list_create();
|
||||||
|
this->pending_updates = 0;
|
||||||
this->keyingtry = 0;
|
this->keyingtry = 0;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
+20
-3
@@ -432,6 +432,22 @@ struct ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
bool (*has_condition) (ike_sa_t *this, ike_condition_t condition);
|
bool (*has_condition) (ike_sa_t *this, ike_condition_t condition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the number of queued MOBIKE address updates.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @return number of pending updates
|
||||||
|
*/
|
||||||
|
u_int32_t (*get_pending_updates)(ike_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the number of queued MOBIKE address updates.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param updates number of pending updates
|
||||||
|
*/
|
||||||
|
void (*set_pending_updates)(ike_sa_t *this, u_int32_t updates);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initiate a new connection.
|
* @brief Initiate a new connection.
|
||||||
*
|
*
|
||||||
@@ -510,10 +526,11 @@ struct ike_sa_t {
|
|||||||
* If MOBIKE is supported, addresses are updated; If not, the tunnel is
|
* If MOBIKE is supported, addresses are updated; If not, the tunnel is
|
||||||
* restarted.
|
* restarted.
|
||||||
*
|
*
|
||||||
* @param
|
* @param this calling object
|
||||||
* @return
|
* @param address TRUE if address list changed, FALSE otherwise
|
||||||
|
* @return SUCCESS, FAILED, DESTROY_ME
|
||||||
*/
|
*/
|
||||||
status_t (*roam)(ike_sa_t *this);
|
status_t (*roam)(ike_sa_t *this, bool address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Processes a incoming IKEv2-Message.
|
* @brief Processes a incoming IKEv2-Message.
|
||||||
|
|||||||
@@ -719,6 +719,10 @@ static status_t process_request(private_task_manager_t *this,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (task)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
|||||||
@@ -51,16 +51,6 @@ struct private_ike_mobike_t {
|
|||||||
*/
|
*/
|
||||||
bool initiator;
|
bool initiator;
|
||||||
|
|
||||||
/**
|
|
||||||
* local host to roam to
|
|
||||||
*/
|
|
||||||
host_t *me;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* remote host to roam to
|
|
||||||
*/
|
|
||||||
host_t *other;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cookie2 value to verify new addresses
|
* cookie2 value to verify new addresses
|
||||||
*/
|
*/
|
||||||
@@ -70,6 +60,16 @@ struct private_ike_mobike_t {
|
|||||||
* NAT discovery reusing the IKE_NATD task
|
* NAT discovery reusing the IKE_NATD task
|
||||||
*/
|
*/
|
||||||
ike_natd_t *natd;
|
ike_natd_t *natd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use task to update addresses
|
||||||
|
*/
|
||||||
|
bool roam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* include address list update
|
||||||
|
*/
|
||||||
|
bool address;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,6 +138,11 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
|
|||||||
this->ike_sa->add_additional_address(this->ike_sa, host);
|
this->ike_sa->add_additional_address(this->ike_sa, host);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case UPDATE_SA_ADDRESSES:
|
||||||
|
{
|
||||||
|
this->roam = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case NO_ADDITIONAL_ADDRESSES:
|
case NO_ADDITIONAL_ADDRESSES:
|
||||||
{
|
{
|
||||||
flush_additional_addresses(this);
|
flush_additional_addresses(this);
|
||||||
@@ -200,6 +205,25 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message)
|
|||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update addresses of associated CHILD_SAs
|
||||||
|
*/
|
||||||
|
static void update_children(private_ike_mobike_t *this)
|
||||||
|
{
|
||||||
|
iterator_t *iterator;
|
||||||
|
child_sa_t *child_sa;
|
||||||
|
|
||||||
|
iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
|
||||||
|
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||||
|
{
|
||||||
|
child_sa->update_hosts(child_sa,
|
||||||
|
this->ike_sa->get_my_host(this->ike_sa),
|
||||||
|
this->ike_sa->get_other_host(this->ike_sa),
|
||||||
|
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of task_t.process for initiator
|
* Implementation of task_t.process for initiator
|
||||||
*/
|
*/
|
||||||
@@ -211,16 +235,20 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
|
|||||||
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
|
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
|
||||||
build_address_list(this, message);
|
build_address_list(this, message);
|
||||||
}
|
}
|
||||||
else if (this->me || this->other)
|
else
|
||||||
{ /* address change */
|
{
|
||||||
message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
|
if (this->roam)
|
||||||
build_address_list(this, message);
|
|
||||||
/* set new addresses */
|
|
||||||
this->ike_sa->update_hosts(this->ike_sa, this->me, this->other);
|
|
||||||
if (this->natd)
|
|
||||||
{
|
{
|
||||||
this->natd->task.build(&this->natd->task, message);
|
message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
|
||||||
}
|
}
|
||||||
|
if (this->address)
|
||||||
|
{
|
||||||
|
build_address_list(this, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->natd = ike_natd_create(this->ike_sa, this->initiator);
|
||||||
|
this->natd->task.build(&this->natd->task, message);
|
||||||
|
update_children(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
@@ -239,6 +267,16 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message)
|
|||||||
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
||||||
{
|
{
|
||||||
process_payloads(this, message);
|
process_payloads(this, message);
|
||||||
|
if (this->roam)
|
||||||
|
{
|
||||||
|
host_t *me, *other;
|
||||||
|
|
||||||
|
me = message->get_destination(message);
|
||||||
|
other = message->get_source(message);
|
||||||
|
this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
|
||||||
|
this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
|
||||||
|
}
|
||||||
|
|
||||||
if (this->natd)
|
if (this->natd)
|
||||||
{
|
{
|
||||||
this->natd->task.process(&this->natd->task, message);
|
this->natd->task.process(&this->natd->task, message);
|
||||||
@@ -268,6 +306,10 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
|
|||||||
{
|
{
|
||||||
this->natd->task.build(&this->natd->task, message);
|
this->natd->task.build(&this->natd->task, message);
|
||||||
}
|
}
|
||||||
|
if (this->roam)
|
||||||
|
{
|
||||||
|
update_children(this);
|
||||||
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
@@ -287,11 +329,23 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
|
|||||||
}
|
}
|
||||||
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
||||||
{
|
{
|
||||||
|
u_int32_t updates = this->ike_sa->get_pending_updates(this->ike_sa) - 1;
|
||||||
|
this->ike_sa->set_pending_updates(this->ike_sa, updates);
|
||||||
|
if (updates > 0)
|
||||||
|
{
|
||||||
|
/* newer update queued, ignore this one */
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
process_payloads(this, message);
|
process_payloads(this, message);
|
||||||
if (this->natd)
|
if (this->natd)
|
||||||
{
|
{
|
||||||
this->natd->task.process(&this->natd->task, message);
|
this->natd->task.process(&this->natd->task, message);
|
||||||
}
|
}
|
||||||
|
if (this->roam)
|
||||||
|
{
|
||||||
|
/* update again, as NAT state may have changed */
|
||||||
|
update_children(this);
|
||||||
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
@@ -300,13 +354,12 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
|
|||||||
/**
|
/**
|
||||||
* Implementation of ike_mobike_t.roam.
|
* Implementation of ike_mobike_t.roam.
|
||||||
*/
|
*/
|
||||||
static void roam(private_ike_mobike_t *this, host_t *me, host_t *other)
|
static void roam(private_ike_mobike_t *this, bool address)
|
||||||
{
|
{
|
||||||
this->me = me;
|
this->roam = TRUE;
|
||||||
this->other = other;
|
this->address = address;
|
||||||
|
this->ike_sa->set_pending_updates(this->ike_sa,
|
||||||
/* include NAT detection when roaming */
|
this->ike_sa->get_pending_updates(this->ike_sa) + 1);
|
||||||
this->natd = ike_natd_create(this->ike_sa, this->initiator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -322,12 +375,8 @@ static task_type_t get_type(private_ike_mobike_t *this)
|
|||||||
*/
|
*/
|
||||||
static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
|
static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->me);
|
|
||||||
DESTROY_IF(this->other);
|
|
||||||
chunk_free(&this->cookie2);
|
chunk_free(&this->cookie2);
|
||||||
this->ike_sa = ike_sa;
|
this->ike_sa = ike_sa;
|
||||||
this->me = NULL;
|
|
||||||
this->other = NULL;
|
|
||||||
if (this->natd)
|
if (this->natd)
|
||||||
{
|
{
|
||||||
this->natd->task.migrate(&this->natd->task, ike_sa);
|
this->natd->task.migrate(&this->natd->task, ike_sa);
|
||||||
@@ -339,8 +388,6 @@ static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
|
|||||||
*/
|
*/
|
||||||
static void destroy(private_ike_mobike_t *this)
|
static void destroy(private_ike_mobike_t *this)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->me);
|
|
||||||
DESTROY_IF(this->other);
|
|
||||||
chunk_free(&this->cookie2);
|
chunk_free(&this->cookie2);
|
||||||
if (this->natd)
|
if (this->natd)
|
||||||
{
|
{
|
||||||
@@ -356,7 +403,7 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
|
|||||||
{
|
{
|
||||||
private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t);
|
private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t);
|
||||||
|
|
||||||
this->public.roam = (void(*)(ike_mobike_t*, host_t *, host_t *))roam;
|
this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
|
||||||
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
|
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
|
||||||
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
|
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
|
||||||
this->public.task.destroy = (void(*)(task_t*))destroy;
|
this->public.task.destroy = (void(*)(task_t*))destroy;
|
||||||
@@ -374,8 +421,8 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
|
|||||||
|
|
||||||
this->ike_sa = ike_sa;
|
this->ike_sa = ike_sa;
|
||||||
this->initiator = initiator;
|
this->initiator = initiator;
|
||||||
this->me = NULL;
|
this->roam = FALSE;
|
||||||
this->other = NULL;
|
this->address = TRUE;
|
||||||
this->cookie2 = chunk_empty;
|
this->cookie2 = chunk_empty;
|
||||||
this->natd = NULL;
|
this->natd = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -54,13 +54,10 @@ struct ike_mobike_t {
|
|||||||
/**
|
/**
|
||||||
* @brief Use the task to roam to other addresses.
|
* @brief Use the task to roam to other addresses.
|
||||||
*
|
*
|
||||||
* Supplied hosts may be NULL to reuse existing IKE_SA hosts.
|
|
||||||
*
|
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param me local host to roam to, or NULL
|
* @param address TRUE to include address list update
|
||||||
* @param other remote host to roam to, or NULL
|
|
||||||
*/
|
*/
|
||||||
void (*roam)(ike_mobike_t *this, host_t *me, host_t *other);
|
void (*roam)(ike_mobike_t *this, bool address);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user