From: David Woodhouse Date: Thu, 2 Dec 2010 11:00:03 +0000 (+0000) Subject: gresolv: Implement RFC3484 rule 9 (prefer longest matching prefix) X-Git-Tag: 2.0_alpha~2062 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c969404724b19204bc1ef1634800f2b70572a297;p=framework%2Fconnectivity%2Fconnman.git gresolv: Implement RFC3484 rule 9 (prefer longest matching prefix) --- diff --git a/gweb/gresolv.c b/gweb/gresolv.c index ed1ccab..0c7613d 100644 --- a/gweb/gresolv.c +++ b/gweb/gresolv.c @@ -920,6 +920,41 @@ static int rfc3484_compare(const void *__one, const void *__two) return one->dst_scope - two->dst_scope; /* Rule 9: Use longest matching prefix */ + if (one->dst.sa.sa_family == AF_INET) { + /* Rule 9 is meaningless and counterproductive for Legacy IP + unless perhaps we can tell that it's actually on the local + subnet. But we don't (yet) have local interface config + information, so do nothing here for Legacy IP for now. */ + } else { + int i; + + for (i = 0; i < 4; i++) { + guint32 cmp_one, cmp_two; + + cmp_one = one->src.sin6.sin6_addr.s6_addr32[i] ^ + one->dst.sin6.sin6_addr.s6_addr32[i]; + cmp_two = two->src.sin6.sin6_addr.s6_addr32[i] ^ + two->dst.sin6.sin6_addr.s6_addr32[i]; + + if (!cmp_two && !cmp_one) + continue; + + if (cmp_one && !cmp_two) + return 1; + if (cmp_two && !cmp_one) + return -1; + + /* g_bit_storage() is effectively fls() */ + cmp_one = g_bit_storage(ntohl(cmp_one)); + cmp_two = g_bit_storage(ntohl(cmp_two)); + + if (cmp_one == cmp_two) + break; + + return cmp_one - cmp_two; + } + } + /* Rule 10: Otherwise, leave the order unchanged */ if (one < two)