summaryrefslogtreecommitdiff
path: root/gweb
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2010-12-02 09:14:51 +0000
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-12-02 09:14:51 +0000
commit7b3b0f94b4fde0071c1c27d904ed3086b8a074ac (patch)
tree9e6ec4efd9901d0ea4f76e14698b0739355928a7 /gweb
parent39195daf950673f5b1da2f8b51c80711d46de718 (diff)
downloadconnman-7b3b0f94b4fde0071c1c27d904ed3086b8a074ac.tar.gz
connman-7b3b0f94b4fde0071c1c27d904ed3086b8a074ac.tar.bz2
connman-7b3b0f94b4fde0071c1c27d904ed3086b8a074ac.zip
gresolv: First partial implementation for RFC3484 sorting
Diffstat (limited to 'gweb')
-rw-r--r--gweb/gresolv.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/gweb/gresolv.c b/gweb/gresolv.c
index a74e54f7..a5fc1524 100644
--- a/gweb/gresolv.c
+++ b/gweb/gresolv.c
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
+#include <stdlib.h>
#include <resolv.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -831,6 +832,50 @@ static int match_gai_table(struct sockaddr *sa, const struct gai_table *tbl)
}
}
+static int rfc3484_compare(const void *__one, const void *__two)
+{
+ const struct sort_result *one = __one;
+ const struct sort_result *two = __two;
+
+ /* Rule 1: Avoid unusable destinations */
+ if (one->reachable && !two->reachable)
+ return -1;
+ else if (two->reachable && !one->reachable)
+ return 1;
+
+ /* Rule 2: Prefer matching scope */
+
+ /* Rule 3: Avoid deprecated addresses */
+
+ /* Rule 4: Prefer home addresses */
+
+ /* Rule 5: Prefer matching label */
+ if (one->dst_label == one->src_label &&
+ two->dst_label != two->src_label)
+ return -1;
+ else if (two->dst_label == two->src_label &&
+ one->dst_label != one->src_label)
+ return 1;
+
+ /* Rule 6: Prefer higher precedence */
+ if (one->precedence > two->precedence)
+ return -1;
+ else if (two->precedence > one->precedence)
+ return 1;
+
+ /* Rule 7: Prefer native transport */
+
+ /* Rule 8: Prefer smaller scope */
+
+ /* Rule 9: Use longest matching prefix */
+
+ /* Rule 10: Otherwise, leave the order unchanged */
+ if (one < two)
+ return -1;
+ else
+ return 1;
+}
+
static void rfc3484_sort_results(struct resolv_lookup *lookup)
{
int i;
@@ -842,5 +887,7 @@ static void rfc3484_sort_results(struct resolv_lookup *lookup)
res->dst_label = match_gai_table(&res->dst.sa, gai_labels);
res->src_label = match_gai_table(&res->src.sa, gai_labels);
}
- /* FIXME: Actually *sort* them... */
+
+ qsort(lookup->results, lookup->nr_results, sizeof(struct sort_result),
+ rfc3484_compare);
}