diff options
Diffstat (limited to 'src/pluto/connections.c')
-rw-r--r-- | src/pluto/connections.c | 59 |
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) |