summaryrefslogtreecommitdiffstats
path: root/common/socket.c
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/socket.c
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/socket.c')
-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)
394 394
395 /* use if address is equal */ 395 /* use if address is equal */
396 if (memcmp(&addr->sin6_addr.s6_addr, &addr_in->sin6_addr.s6_addr, sizeof(addr_in->sin6_addr.s6_addr)) == 0) { 396 if (memcmp(&addr->sin6_addr.s6_addr, &addr_in->sin6_addr.s6_addr, sizeof(addr_in->sin6_addr.s6_addr)) == 0) {
397 res = addr_in->sin6_scope_id;
398 /* if scope id equals the requested one then assume it was valid */ 397 /* if scope id equals the requested one then assume it was valid */
399 if (addr->sin6_scope_id == addr_in->sin6_scope_id) { 398 if (addr->sin6_scope_id == addr_in->sin6_scope_id) {
399 res = addr_in->sin6_scope_id;
400 break; 400 break;
401 } else { 401 } else {
402 if ((addr_in->sin6_scope_id > addr->sin6_scope_id) && (res >= 0)) {
403 // use last valid scope id as we're past the requested scope id
404 break;
405 }
406 res = addr_in->sin6_scope_id;
402 continue; 407 continue;
403 } 408 }
404 } 409 }
@@ -408,11 +413,16 @@ static int32_t _sockaddr_in6_scope_id(struct sockaddr_in6* addr)
408 continue; 413 continue;
409 } 414 }
410 415
411 /* set the scope id of this interface as most likely candidate */ 416 if ((addr_in->sin6_scope_id > addr->sin6_scope_id) && (res >= 0)) {
417 // use last valid scope id as we're past the requested scope id
418 break;
419 }
420
412 res = addr_in->sin6_scope_id; 421 res = addr_in->sin6_scope_id;
413 422
414 /* if scope id equals the requested one then assume it was valid */ 423 /* if scope id equals the requested one then assume it was valid */
415 if (addr->sin6_scope_id == addr_in->sin6_scope_id) { 424 if (addr->sin6_scope_id == addr_in->sin6_scope_id) {
425 /* set the scope id of this interface as most likely candidate */
416 break; 426 break;
417 } 427 }
418 } 428 }