From: Pavel Šimerda Date: Tue, 14 Jan 2014 14:34:52 +0000 (+0100) Subject: core: sort IPv6 paths before IPv4 paths X-Git-Url: https://www.sourceware.org/git/?a=commitdiff_plain;h=1ae3bf4088befa936a371343d56f1a80c7cd3e71;p=netresolve.git core: sort IPv6 paths before IPv4 paths --- diff --git a/TODO b/TODO index afd9ae7..f369c09 100644 --- a/TODO +++ b/TODO @@ -2,10 +2,11 @@ ## Core library - * Return items in the right order - - http://tools.ietf.org/html/rfc6724 + * Improve path ordering - use priority from DNS SRV - - randomize order using weight from DNS SRV + - use weight from DNS SRV for randomized ordering + - use rules from http://tools.ietf.org/html/rfc6724 + - use /etc/gai.conf * Support multiple concurrent queries per channel * Support reverse lookup * Improve socket API and happy eyeballs diff --git a/lib/backend.c b/lib/backend.c index 8df323c..a827361 100644 --- a/lib/backend.c +++ b/lib/backend.c @@ -106,6 +106,17 @@ path_callback(int socktype, int protocol, int port, void *user_data) 0, 0); } +static int +path_cmp(struct netresolve_path *p1, struct netresolve_path *p2) +{ + if (p1->node.family == AF_INET6 && p2->node.family == AF_INET) + return -1; + if (p1->node.family == AF_INET && p2->node.family == AF_INET6) + return 1; + + return 0; +} + void netresolve_backend_add_path(netresolve_query_t channel, int family, const void *address, int ifindex, @@ -114,6 +125,7 @@ netresolve_backend_add_path(netresolve_query_t channel, { struct netresolve_response *response = &channel->response; struct netresolve_path path; + int i; if (family == AF_UNIX && socktype == -1) { netresolve_backend_add_path(channel, family, address, 0, SOCK_STREAM, 0, 0, 0, 0); @@ -152,8 +164,14 @@ netresolve_backend_add_path(netresolve_query_t channel, path.priority = priority; path.weight = weight; + for (i = 0; i < response->pathcount; i++) + if (path_cmp(&path, &response->paths[i]) < 0) + break; + response->paths = realloc(response->paths, (response->pathcount + 1) * sizeof path); - memcpy(&response->paths[response->pathcount++], &path, sizeof path); + memmove(&response->paths[i+1], &response->paths[i], + (response->pathcount++ - i) * sizeof *response->paths); + memcpy(&response->paths[i], &path, sizeof path); debug("added path: %s", netresolve_get_path_string(channel, response->pathcount - 1)); diff --git a/tests/data/any b/tests/data/any index bf2a55f..cfe61bd 100644 --- a/tests/data/any +++ b/tests/data/any @@ -1,4 +1,4 @@ response netresolve 0.0.1 -path 0.0.0.0 any any 0 0 0 path :: any any 0 0 0 +path 0.0.0.0 any any 0 0 0 diff --git a/tests/data/localhost b/tests/data/localhost index c5119a2..4271fa1 100644 --- a/tests/data/localhost +++ b/tests/data/localhost @@ -1,4 +1,4 @@ response netresolve 0.0.1 -path 127.0.0.1 any any 0 0 0 path ::1 any any 0 0 0 +path 127.0.0.1 any any 0 0 0 diff --git a/tests/data/services b/tests/data/services index e4c1969..4d13e72 100644 --- a/tests/data/services +++ b/tests/data/services @@ -1,6 +1,6 @@ response netresolve 0.0.1 -path 0.0.0.0 stream tcp 1021 0 0 -path 0.0.0.0 dgram udp 1021 0 0 path :: stream tcp 1021 0 0 path :: dgram udp 1021 0 0 +path 0.0.0.0 stream tcp 1021 0 0 +path 0.0.0.0 dgram udp 1021 0 0