summaryrefslogtreecommitdiff
path: root/src/pluto/connections.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/connections.c')
-rw-r--r--src/pluto/connections.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index c4d5dae4d..952e722d2 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.c,v 1.43 2006/04/29 18:16:02 as Exp $
+ * RCSID $Id: connections.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <string.h>
@@ -58,6 +58,7 @@
#include "whack.h"
#include "alg_info.h"
#include "ike_alg.h"
+#include "kernel_alg.h"
#include "nat_traversal.h"
#include "virtual.h"
@@ -638,13 +639,24 @@ format_end(char *buf
strcpy(&host_id[len < 0? (ptrdiff_t)sizeof(host_id)-2 : 1 + len], "]");
}
+ /* [---hop] */
+ hop[0] = '\0';
+ hop_sep = "";
+ if (that != NULL && !sameaddr(&this->host_nexthop, &that->host_addr))
+ {
+ addrtot(&this->host_nexthop, 0, hop, sizeof(hop));
+ hop_sep = "---";
+ }
+
if (is_left)
- snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s"
+ snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
, open_brackets, client, close_brackets, client_sep
, this->allow_any? "%":""
- , host, host_port, host_id, protoport);
+ , host, host_port, host_id, protoport
+ , hop_sep, hop);
else
- snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s"
+ snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
+ , hop, hop_sep
, this->allow_any? "%":""
, host, host_port, host_id, protoport, client_sep
, open_brackets, client, close_brackets);
@@ -3016,11 +3028,10 @@ ISAKMP_SA_established(struct connection *c, so_serial_t serial)
{
struct connection *next = d->ac_next; /* might move underneath us */
- if (d->kind >= CK_PERMANENT
+ if (d->kind >= CK_PERMANENT
&& same_id(&c->spd.this.id, &d->spd.this.id)
&& same_id(&c->spd.that.id, &d->spd.that.id)
- && (!sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr) ||
- (c->spd.that.host_port != d->spd.that.host_port)))
+ && !sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr))
{
release_connection(d, FALSE);
}
@@ -3257,22 +3268,21 @@ find_host_connection(const ip_address *me, u_int16_t my_port
* less important than the disadvantages, so after FreeS/WAN 1.9, we
* don't do this.
*/
+#define PRIO_NO_MATCH_FOUND 2048
+
struct connection *
refine_host_connection(const struct state *st, const struct id *peer_id
, chunk_t peer_ca)
{
struct connection *c = st->st_connection;
- u_int16_t auth = st->st_oakley.auth;
struct connection *d;
struct connection *best_found = NULL;
+ u_int16_t auth = st->st_oakley.auth;
lset_t auth_policy;
const chunk_t *psk = NULL;
bool wcpip; /* wildcard Peer IP? */
-
+ int best_prio = PRIO_NO_MATCH_FOUND;
int wildcards, our_pathlen, peer_pathlen;
- int best_wildcards = MAX_WILDCARDS;
- int best_our_pathlen = MAX_CA_PATH_LEN;
- int best_peer_pathlen = MAX_CA_PATH_LEN;
if (same_id(&c->spd.that.id, peer_id)
&& trusted_ca(peer_ca, c->spd.that.ca, &peer_pathlen)
@@ -3340,17 +3350,22 @@ refine_host_connection(const struct state *st, const struct id *peer_id
, d->spd.that.ca, &peer_pathlen);
bool matching_request = match_requested_ca(c->requested_ca
, d->spd.this.ca, &our_pathlen);
- bool match = matching_id && matching_auth &&
- matching_trust && matching_request;
+ bool match = matching_id && matching_auth && matching_trust;
+
+ int prio = (MAX_WILDCARDS + 1) * !matching_request + wildcards;
+
+ prio = (MAX_CA_PATH_LEN + 1) * prio + peer_pathlen;
+ prio = (MAX_CA_PATH_LEN + 1) * prio + our_pathlen;
DBG(DBG_CONTROLMORE,
- DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s)"
+ DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s, prio: %4d)"
, d->name
, match ? "full":" no"
, match_name[matching_id]
, match_name[matching_auth]
, match_name[matching_trust]
- , match_name[matching_request])
+ , match_name[matching_request]
+ , match ? prio:PRIO_NO_MATCH_FOUND)
)
/* do we have a match? */
@@ -3404,20 +3419,18 @@ refine_host_connection(const struct state *st, const struct id *peer_id
/* d has passed all the tests.
* We'll go with it if the Peer ID was an exact match.
*/
- if (match && wildcards == 0 && peer_pathlen == 0 && our_pathlen == 0)
+ if (prio == 0)
+ {
return d;
+ }
/* We'll remember it as best_found in case an exact
* match doesn't come along.
*/
- if (best_found == NULL || wildcards < best_wildcards
- || ((wildcards == best_wildcards && peer_pathlen < best_peer_pathlen)
- || (peer_pathlen == best_peer_pathlen && our_pathlen < best_our_pathlen)))
+ if (prio < best_prio)
{
best_found = d;
- best_wildcards = wildcards;
- best_peer_pathlen = peer_pathlen;
- best_our_pathlen = our_pathlen;
+ best_prio = prio;
}
}
if (wcpip)