Skip to content

Commit

Permalink
ikev2: change protocol/port matching algorithms from O(n**2) to O(n)
Browse files Browse the repository at this point in the history
  • Loading branch information
vukasink committed Jan 29, 2018
1 parent a903e20 commit 8000cd3
Showing 1 changed file with 65 additions and 58 deletions.
123 changes: 65 additions & 58 deletions programs/pluto/ikev2_child.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,10 @@ int ikev2_evaluate_connection_protocol_fit(const struct connection *d,
int *best_tsi_i,
int *best_tsr_i)
{
int tsi_ni;
int tsi_ni, tsr_ni;
int bestfit_pr = -1;
int bestfit_i_temp = 0, bestfit_r_temp = 0;
int best_tsi_temp = -1, best_tsr_temp = -1;
const struct end *ei, *er;
int narrowing = (d->policy & POLICY_IKEV2_ALLOW_NARROWING);

Expand All @@ -394,44 +396,47 @@ int ikev2_evaluate_connection_protocol_fit(const struct connection *d,
ei = &sr->that;
er = &sr->this;
}
/* compare tsi/r array to this/that, evaluating protocol how well it fits */
/* ??? stupid n**2 algorithm */
/* compare tsi array to this */
for (tsi_ni = 0; tsi_ni < tsi_n; tsi_ni++) {
int tsr_ni;

int fitrange_i = ikev2_match_protocol(ei->protocol, tsi[tsi_ni].ipprotoid,
role == ORIGINAL_RESPONDER && narrowing,
role == ORIGINAL_INITIATOR && narrowing,
"tsi", tsi_ni);

if (fitrange_i == 0)
continue; /* save effort! */

for (tsr_ni = 0; tsr_ni < tsr_n; tsr_ni++) {
int fitrange_r = ikev2_match_protocol(er->protocol, tsr[tsr_ni].ipprotoid,
role == ORIGINAL_RESPONDER && narrowing,
role == ORIGINAL_INITIATOR && narrowing,
"tsr", tsr_ni);

int matchiness;

if (fitrange_r == 0)
continue; /* save effort! */

matchiness = fitrange_i + fitrange_r; /* ??? arbitrary objective function */
if (fitrange_i > bestfit_i_temp) {
bestfit_i_temp = fitrange_i;
best_tsi_temp = tsi_ni;
if (bestfit_i_temp == 255) /* we can't find a better one */
break;
}
}
/* compare tsr array to that */
for (tsr_ni = 0; tsr_ni < tsr_n; tsr_ni++) {
int fitrange_r = ikev2_match_protocol(er->protocol, tsr[tsr_ni].ipprotoid,
role == ORIGINAL_RESPONDER && narrowing,
role == ORIGINAL_INITIATOR && narrowing,
"tsr", tsr_ni);

if (matchiness > bestfit_pr) {
*best_tsi_i = tsi_ni;
*best_tsr_i = tsr_ni;
bestfit_pr = matchiness;
DBG(DBG_CONTROL,
DBG_log(" best protocol fit so far: tsi[%d] fitrange_i %d, tsr[%d] fitrange_r %d, matchiness %d",
*best_tsi_i, fitrange_i,
*best_tsr_i, fitrange_r,
matchiness));
}
if (fitrange_r > bestfit_r_temp) {
bestfit_r_temp = fitrange_r;
best_tsr_temp = tsr_ni;
if (bestfit_i_temp == 255) /* we can't find a better one */
break;
}
}
/* if we found at least one match (and thus the best) in each */
if (best_tsi_temp != -1 && best_tsr_temp != -1 ) {
*best_tsi_i = best_tsi_temp;
*best_tsr_i = best_tsr_temp;
bestfit_pr = bestfit_i_temp + bestfit_r_temp;
DBG(DBG_CONTROL,
DBG_log(" best protocol fit: tsi[%d] fitrange_i %d, tsr[%d] fitrange_r %d, matchiness %d",
*best_tsi_i, bestfit_i_temp,
*best_tsr_i, bestfit_r_temp,
bestfit_pr));
}

DBG(DBG_CONTROL, DBG_log(" protocol_fitness %d", bestfit_pr));
return bestfit_pr;
}
Expand Down Expand Up @@ -489,8 +494,10 @@ int ikev2_evaluate_connection_port_fit(const struct connection *d,
int *best_tsi_i,
int *best_tsr_i)
{
int tsi_ni;
int tsi_ni, tsr_ni;
int bestfit_p = -1;
int bestfit_i_temp = 0, bestfit_r_temp = 0;
int best_tsi_temp = -1, best_tsr_temp = -1;
const struct end *ei, *er;
int narrowing = (d->policy & POLICY_IKEV2_ALLOW_NARROWING);

Expand All @@ -501,43 +508,43 @@ int ikev2_evaluate_connection_port_fit(const struct connection *d,
ei = &sr->that;
er = &sr->this;
}
/* compare tsi/r array to this/that, evaluating how well each port range fits */
/* ??? stupid n**2 algorithm */
/* compare tsi array to this */
for (tsi_ni = 0; tsi_ni < tsi_n; tsi_ni++) {
int tsr_ni;

int fitrange_i = ikev2_match_port_range(ei->port, tsi[tsi_ni],
role == ORIGINAL_RESPONDER && narrowing,
role == ORIGINAL_INITIATOR && narrowing,
"tsi", tsi_ni);

if (fitrange_i == 0)
continue; /* save effort! */

for (tsr_ni = 0; tsr_ni < tsr_n; tsr_ni++) {
int fitrange_r = ikev2_match_port_range(er->port, tsr[tsr_ni],
role == ORIGINAL_RESPONDER && narrowing,
role == ORIGINAL_INITIATOR && narrowing,
"tsr", tsr_ni);

int matchiness;

if (fitrange_r == 0)
continue; /* no match */

matchiness = fitrange_i + fitrange_r; /* ??? arbitrary objective function */
if (fitrange_i > bestfit_i_temp) {
bestfit_i_temp = fitrange_i;
best_tsi_temp = tsi_ni;
}
}
/* compare tsr array to that */
for (tsr_ni = 0; tsr_ni < tsr_n; tsr_ni++) {
int fitrange_r = ikev2_match_port_range(er->port, tsr[tsr_ni],
role == ORIGINAL_RESPONDER && narrowing,
role == ORIGINAL_INITIATOR && narrowing,
"tsr", tsr_ni);

if (matchiness > bestfit_p) {
*best_tsi_i = tsi_ni;
*best_tsr_i = tsr_ni;
bestfit_p = matchiness;
DBG(DBG_CONTROL,
DBG_log(" best ports fit so far: tsi[%d] fitrange_i %d, tsr[%d] fitrange_r %d, matchiness %d",
*best_tsi_i, fitrange_i,
*best_tsr_i, fitrange_r,
matchiness));
}
if (fitrange_r > bestfit_r_temp) {
bestfit_r_temp = fitrange_r;
best_tsr_temp = tsr_ni;
}
}
/* if we found at least one match (and thus the best) in each */
if (best_tsi_temp != -1 && best_tsr_temp != -1 ) {
*best_tsi_i = best_tsi_temp;
*best_tsr_i = best_tsr_temp;
bestfit_p = bestfit_i_temp + bestfit_r_temp;
DBG(DBG_CONTROL,
DBG_log(" best ports fit: tsi[%d] fitrange_i %d, tsr[%d] fitrange_r %d, matchiness %d",
*best_tsi_i, bestfit_i_temp,
*best_tsr_i, bestfit_r_temp,
bestfit_p));
}

DBG(DBG_CONTROL, DBG_log(" port_fitness %d", bestfit_p));
return bestfit_p;
}
Expand Down

0 comments on commit 8000cd3

Please sign in to comment.