summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2020-06-08 17:57:40 +0200
committerGravatar Martin Szulecki2020-06-08 17:57:40 +0200
commit604a0a23018df80f24113209f36aa407e1624498 (patch)
tree1624e44211b2d4aac2c3d996cd4da468fb670c21 /common
parent1c7ef2a008c77bbb5f26438ded60c5ef1273935b (diff)
downloadlibimobiledevice-604a0a23018df80f24113209f36aa407e1624498.tar.gz
libimobiledevice-604a0a23018df80f24113209f36aa407e1624498.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 749e0ef..a5f9a33 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -394,11 +394,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;
}
}
@@ -408,11 +413,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;
}
}