summaryrefslogtreecommitdiff
path: root/iterator/iter_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'iterator/iter_utils.c')
-rw-r--r--iterator/iter_utils.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 3c14de86e7b41..7bc67da69b2e8 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -484,6 +484,63 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
got_num = num4ok;
*selected_rtt = num4_lowrtt;
}
+ } else if (env->cfg->prefer_ip4) {
+ int got_num4 = 0;
+ int low_rtt4 = 0;
+ int i;
+ int attempt = -1; /* filter to make sure addresses have
+ less attempts on them than the first, to force round
+ robin when all the IPv4 addresses fail */
+ int num6ok = 0; /* number ip6 at low attempt count */
+ int num6_lowrtt = 0;
+ prev = NULL;
+ a = dp->result_list;
+ for(i = 0; i < got_num; i++) {
+ swap_to_front = 0;
+ if(a->addr.ss_family != AF_INET && attempt == -1) {
+ /* if we only have ip6 at low attempt count,
+ * then ip4 is failing, and we need to
+ * select one of the remaining IPv6 addrs */
+ attempt = a->attempts;
+ num6ok++;
+ num6_lowrtt = a->sel_rtt;
+ } else if(a->addr.ss_family != AF_INET && attempt == a->attempts) {
+ num6ok++;
+ if(num6_lowrtt == 0 || a->sel_rtt < num6_lowrtt) {
+ num6_lowrtt = a->sel_rtt;
+ }
+ }
+ if(a->addr.ss_family == AF_INET) {
+ if(attempt == -1) {
+ attempt = a->attempts;
+ } else if(a->attempts > attempt) {
+ break;
+ }
+ got_num4++;
+ swap_to_front = 1;
+ if(low_rtt4 == 0 || a->sel_rtt < low_rtt4) {
+ low_rtt4 = a->sel_rtt;
+ }
+ }
+ /* swap to front if IPv4, or move to next result */
+ if(swap_to_front && prev) {
+ n = a->next_result;
+ prev->next_result = n;
+ a->next_result = dp->result_list;
+ dp->result_list = a;
+ a = n;
+ } else {
+ prev = a;
+ a = a->next_result;
+ }
+ }
+ if(got_num4 > 0) {
+ got_num = got_num4;
+ *selected_rtt = low_rtt4;
+ } else if(num6ok > 0) {
+ got_num = num6ok;
+ *selected_rtt = num6_lowrtt;
+ }
}
return got_num;
}