Hi all.
I stumbled upon to two /* ??? stupid n**2 algorithm */ comments in
ikev2_child.c, in functions
ikev2_evaluate_connection_protocol_fit. and
int ikev2_evaluate_connection_port_fit
I made a patch, trying to reduce it to O(n) algorithm,
it seems right to me, but probably it will be better if more people
examine it, so please do it if you can :)
Here's a github link:
https://github.com/vukasink/libreswan/commit/8000cd325e4897f2e96a644d5bc0172d097f1ec4
but you can also find it attached in this e-mail.
Regards,
Vukasin K.
diff --git a/programs/pluto/ikev2_child.c b/programs/pluto/ikev2_child.c
index fad79c8..9e99c3f 100644
--- a/programs/pluto/ikev2_child.c
+++ b/programs/pluto/ikev2_child.c
@@ -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);
@@ -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;
}
@@ -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);
@@ -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;
}
_______________________________________________
Swan-dev mailing list
[email protected]
https://lists.libreswan.org/mailman/listinfo/swan-dev