diff options
author | Martin Szulecki | 2020-06-08 17:57:40 +0200 |
---|---|---|
committer | Martin Szulecki | 2020-06-08 17:57:40 +0200 |
commit | 604a0a23018df80f24113209f36aa407e1624498 (patch) | |
tree | 1624e44211b2d4aac2c3d996cd4da468fb670c21 /common | |
parent | 1c7ef2a008c77bbb5f26438ded60c5ef1273935b (diff) | |
download | libimobiledevice-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.c | 14 |
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; } } |