summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2020-06-08 18:32:49 +0200
committerGravatar Nikias Bassen2020-06-08 18:32:49 +0200
commitd75d298cf1524919271a4390bb9c30c9effbcd70 (patch)
tree07f52e659c6d9e382361c429d76f346d58f1792f /common
parent7021fc8622a2a4b95ad23ff34d9129d8da0cb187 (diff)
downloadlibusbmuxd-d75d298cf1524919271a4390bb9c30c9effbcd70.tar.gz
libusbmuxd-d75d298cf1524919271a4390bb9c30c9effbcd70.tar.bz2
socket: Fix IPv6 scope id lookup logic to handle another network device problem
The lookup logic preferred to return the last suitable scope id match. This became a problem if there was already a suitable scope id match before that was higher in the interface list. This now chooses the higher last scope id interface match and thus probably in the routing preference.
Diffstat (limited to 'common')
-rw-r--r--common/socket.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/common/socket.c b/common/socket.c
index 86cbf48..fd89c56 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -426,11 +426,16 @@ static int32_t _sockaddr_in6_scope_id(struct sockaddr_in6* addr)
/* use if address is equal */
if (memcmp(&addr->sin6_addr.s6_addr, &addr_in->sin6_addr.s6_addr, sizeof(addr_in->sin6_addr.s6_addr)) == 0) {
- res = addr_in->sin6_scope_id;
/* if scope id equals the requested one then assume it was valid */
if (addr->sin6_scope_id == addr_in->sin6_scope_id) {
+ res = addr_in->sin6_scope_id;
break;
} else {
+ if ((addr_in->sin6_scope_id > addr->sin6_scope_id) && (res >= 0)) {
+ // use last valid scope id as we're past the requested scope id
+ break;
+ }
+ res = addr_in->sin6_scope_id;
continue;
}
}
@@ -440,11 +445,16 @@ static int32_t _sockaddr_in6_scope_id(struct sockaddr_in6* addr)
continue;
}
- /* set the scope id of this interface as most likely candidate */
+ if ((addr_in->sin6_scope_id > addr->sin6_scope_id) && (res >= 0)) {
+ // use last valid scope id as we're past the requested scope id
+ break;
+ }
+
res = addr_in->sin6_scope_id;
/* if scope id equals the requested one then assume it was valid */
if (addr->sin6_scope_id == addr_in->sin6_scope_id) {
+ /* set the scope id of this interface as most likely candidate */
break;
}
}