23
23
import asyncio
24
24
import random
25
25
import sys
26
- from ipaddress import IPv4Address , IPv6Address , _BaseAddress
27
26
from typing import TYPE_CHECKING , Dict , List , Optional , Set , Union , cast
28
27
29
28
from .._cache import DNSCache
50
49
wait_for_future_set_or_timeout ,
51
50
)
52
51
from .._utils .ipaddress import (
52
+ ZeroconfIPv4Address ,
53
+ ZeroconfIPv6Address ,
53
54
cached_ip_addresses ,
54
55
get_ip_address_object_from_record ,
55
56
ip_bytes_and_scope_to_address ,
@@ -187,8 +188,8 @@ def __init__(
187
188
self .type = type_
188
189
self ._name = name
189
190
self .key = name .lower ()
190
- self ._ipv4_addresses : List [IPv4Address ] = []
191
- self ._ipv6_addresses : List [IPv6Address ] = []
191
+ self ._ipv4_addresses : List [ZeroconfIPv4Address ] = []
192
+ self ._ipv6_addresses : List [ZeroconfIPv6Address ] = []
192
193
if addresses is not None :
193
194
self .addresses = addresses
194
195
elif parsed_addresses is not None :
@@ -260,11 +261,11 @@ def addresses(self, value: List[bytes]) -> None:
260
261
)
261
262
if addr .version == 4 :
262
263
if TYPE_CHECKING :
263
- assert isinstance (addr , IPv4Address )
264
+ assert isinstance (addr , ZeroconfIPv4Address )
264
265
self ._ipv4_addresses .append (addr )
265
266
else :
266
267
if TYPE_CHECKING :
267
- assert isinstance (addr , IPv6Address )
268
+ assert isinstance (addr , ZeroconfIPv6Address )
268
269
self ._ipv6_addresses .append (addr )
269
270
270
271
@property
@@ -321,7 +322,7 @@ def addresses_by_version(self, version: IPVersion) -> List[bytes]:
321
322
322
323
def ip_addresses_by_version (
323
324
self , version : IPVersion
324
- ) -> Union [List [IPv4Address ], List [IPv6Address ], List [ _BaseAddress ]]:
325
+ ) -> Union [List [ZeroconfIPv4Address ], List [ZeroconfIPv6Address ]]:
325
326
"""List ip_address objects matching IP version.
326
327
327
328
Addresses are guaranteed to be returned in LIFO (last in, first out)
@@ -334,7 +335,7 @@ def ip_addresses_by_version(
334
335
335
336
def _ip_addresses_by_version_value (
336
337
self , version_value : int_
337
- ) -> Union [List [IPv4Address ], List [IPv6Address ]]:
338
+ ) -> Union [List [ZeroconfIPv4Address ], List [ZeroconfIPv6Address ]]:
338
339
"""Backend for addresses_by_version that uses the raw value."""
339
340
if version_value == _IPVersion_All_value :
340
341
return [* self ._ipv4_addresses , * self ._ipv6_addresses ] # type: ignore[return-value]
@@ -440,9 +441,9 @@ def get_name(self) -> str:
440
441
441
442
def _get_ip_addresses_from_cache_lifo (
442
443
self , zc : "Zeroconf" , now : float_ , type : int_
443
- ) -> List [Union [IPv4Address , IPv6Address ]]:
444
+ ) -> List [Union [ZeroconfIPv4Address , ZeroconfIPv6Address ]]:
444
445
"""Set IPv6 addresses from the cache."""
445
- address_list : List [Union [IPv4Address , IPv6Address ]] = []
446
+ address_list : List [Union [ZeroconfIPv4Address , ZeroconfIPv6Address ]] = []
446
447
for record in self ._get_address_records_from_cache_by_type (zc , type ):
447
448
if record .is_expired (now ):
448
449
continue
@@ -456,7 +457,7 @@ def _set_ipv6_addresses_from_cache(self, zc: "Zeroconf", now: float_) -> None:
456
457
"""Set IPv6 addresses from the cache."""
457
458
if TYPE_CHECKING :
458
459
self ._ipv6_addresses = cast (
459
- "List[IPv6Address ]" ,
460
+ "List[ZeroconfIPv6Address ]" ,
460
461
self ._get_ip_addresses_from_cache_lifo (zc , now , _TYPE_AAAA ),
461
462
)
462
463
else :
@@ -466,7 +467,7 @@ def _set_ipv4_addresses_from_cache(self, zc: "Zeroconf", now: float_) -> None:
466
467
"""Set IPv4 addresses from the cache."""
467
468
if TYPE_CHECKING :
468
469
self ._ipv4_addresses = cast (
469
- "List[IPv4Address ]" ,
470
+ "List[ZeroconfIPv4Address ]" ,
470
471
self ._get_ip_addresses_from_cache_lifo (zc , now , _TYPE_A ),
471
472
)
472
473
else :
@@ -509,24 +510,32 @@ def _process_record_threadsafe(self, zc: "Zeroconf", record: DNSRecord, now: flo
509
510
510
511
if ip_addr .version == 4 :
511
512
if TYPE_CHECKING :
512
- assert isinstance (ip_addr , IPv4Address )
513
+ assert isinstance (ip_addr , ZeroconfIPv4Address )
513
514
ipv4_addresses = self ._ipv4_addresses
514
515
if ip_addr not in ipv4_addresses :
515
516
ipv4_addresses .insert (0 , ip_addr )
516
517
return True
517
- elif ip_addr != ipv4_addresses [0 ]:
518
+ # Use int() to compare the addresses as integers
519
+ # since by default IPv4Address.__eq__ compares the
520
+ # the addresses on version and int which more than
521
+ # we need here since we know the version is 4.
522
+ elif ip_addr .zc_integer != ipv4_addresses [0 ].zc_integer :
518
523
ipv4_addresses .remove (ip_addr )
519
524
ipv4_addresses .insert (0 , ip_addr )
520
525
521
526
return False
522
527
523
528
if TYPE_CHECKING :
524
- assert isinstance (ip_addr , IPv6Address )
529
+ assert isinstance (ip_addr , ZeroconfIPv6Address )
525
530
ipv6_addresses = self ._ipv6_addresses
526
531
if ip_addr not in self ._ipv6_addresses :
527
532
ipv6_addresses .insert (0 , ip_addr )
528
533
return True
529
- elif ip_addr != self ._ipv6_addresses [0 ]:
534
+ # Use int() to compare the addresses as integers
535
+ # since by default IPv6Address.__eq__ compares the
536
+ # the addresses on version and int which more than
537
+ # we need here since we know the version is 6.
538
+ elif ip_addr .zc_integer != self ._ipv6_addresses [0 ].zc_integer :
530
539
ipv6_addresses .remove (ip_addr )
531
540
ipv6_addresses .insert (0 , ip_addr )
532
541
0 commit comments