diff options
Diffstat (limited to 'src/charon/sa/tasks/child_create.c')
-rw-r--r-- | src/charon/sa/tasks/child_create.c | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c index f70730b05..42f34a94b 100644 --- a/src/charon/sa/tasks/child_create.c +++ b/src/charon/sa/tasks/child_create.c @@ -297,7 +297,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) this->mode = MODE_TUNNEL; DBG1(DBG_IKE, "not using tranport mode, not host-to-host"); } - else if (this->ike_sa->is_natt_enabled(this->ike_sa)) + else if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)) { this->mode = MODE_TUNNEL; DBG1(DBG_IKE, "not using tranport mode, connection NATed"); @@ -493,6 +493,7 @@ static void process_payloads(private_child_create_t *this, message_t *message) static status_t build_i(private_child_create_t *this, message_t *message) { host_t *me, *other, *vip; + bool propose_all = FALSE; peer_cfg_t *peer_cfg; switch (message->get_exchange_type(message)) @@ -523,33 +524,53 @@ static status_t build_i(private_child_create_t *this, message_t *message) SIG(CHILD_UP_START, "establishing CHILD_SA"); - me = this->ike_sa->get_my_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); - vip = peer_cfg->get_my_virtual_ip(peer_cfg); + /* reuse virtual IP if we already have one */ + me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE); + if (me == NULL) + { + me = this->ike_sa->get_my_host(this->ike_sa); + } + other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE); + if (other == NULL) + { + other = this->ike_sa->get_other_host(this->ike_sa); + } - if (vip) + /* check if we want a virtual IP, but don't have one */ + if (!this->reqid) + { + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + vip = peer_cfg->get_my_virtual_ip(peer_cfg); + if (vip) + { + propose_all = TRUE; + vip->destroy(vip); + } + } + + if (propose_all) { /* propose a 0.0.0.0/0 subnet when we use virtual ip */ this->tsi = this->config->get_traffic_selectors(this->config, TRUE, NULL, NULL); - vip->destroy(vip); } else - { /* but shorten a 0.0.0.0/0 subnet to the actual address if host2host */ + { /* but shorten a 0.0.0.0/0 subnet for host2host/we already have a vip */ this->tsi = this->config->get_traffic_selectors(this->config, TRUE, NULL, me); } this->tsr = this->config->get_traffic_selectors(this->config, FALSE, NULL, other); + this->proposals = this->config->get_proposals(this->config, this->dh_group == MODP_NONE); this->mode = this->config->get_mode(this->config); - this->child_sa = child_sa_create(me, other, - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa), - this->config, this->reqid, - this->ike_sa->is_natt_enabled(this->ike_sa)); + this->child_sa = child_sa_create( + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid, + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS) { @@ -609,9 +630,21 @@ static status_t process_r(private_child_create_t *this, message_t *message) peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); if (peer_cfg) { - this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr, this->tsi, - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa)); + host_t *me, *other; + + me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE); + if (me == NULL) + { + me = this->ike_sa->get_my_host(this->ike_sa); + } + other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE); + if (other == NULL) + { + other = this->ike_sa->get_other_host(this->ike_sa); + } + + this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr, + this->tsi, me, other); } return NEED_MORE; } @@ -660,12 +693,12 @@ static status_t build_r(private_child_create_t *this, message_t *message) return SUCCESS; } - this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa), - this->config, this->reqid, - this->ike_sa->is_natt_enabled(this->ike_sa)); + this->child_sa = child_sa_create( + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid, + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); switch (select_and_install(this, no_dh)) { |