-
Notifications
You must be signed in to change notification settings - Fork 227
Call UpdateService for SRV & A/AAAA records as well as TXT #239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
43e1b24
d314896
f40649a
6a3deb7
4a1f7e5
2b258fd
064056b
cc78868
aa3e947
c1d5625
dc570c9
d8f3508
902548b
f3d6bf2
53cd650
700a183
d2cfb86
23aa41f
2c16b31
98bdbfd
a3ab378
a42ee2c
5d69f91
c2d4b0c
6831c2e
38c3ed9
23e4af1
4bb5539
dc653d1
d086b82
a6da721
592c0e1
982f75b
4b48dd9
56955ed
abc4773
73ae509
f142584
aad875d
7430ca0
9fe89c6
55a0026
4b2c476
4e6c84d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -35,6 +35,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| import threading | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import time | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from collections import OrderedDict | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Dict, List, Optional, Sequence, Union, cast | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any, Callable, Set, Tuple # noqa # used in type hints | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1121,8 +1122,9 @@ def __init__(self) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def add(self, entry: DNSRecord) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Adds an entry""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Insert first in list so get returns newest entry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.setdefault(entry.key, []).insert(0, entry) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Insert last in list, get will return newest entry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # iteration will result in last update winning | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.setdefault(entry.key, []).append(entry) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def remove(self, entry: DNSRecord) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Removes an entry""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1142,7 +1144,7 @@ def get(self, entry: DNSEntry) -> Optional[DNSRecord]: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| matching entry.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| list_ = self.cache[entry.key] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for cached_entry in list_: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for cached_entry in reversed(list_): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if entry.__eq__(cached_entry): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return cached_entry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1164,7 +1166,7 @@ def entries_with_name(self, name: str) -> List[DNSRecord]: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def current_entry_with_name_and_alias(self, name: str, alias: str) -> Optional[DNSRecord]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| now = current_time_millis() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for record in self.entries_with_name(name): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for record in reversed(self.entries_with_name(name)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| record.type == _TYPE_PTR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and not record.is_expired(now) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1383,7 +1385,7 @@ def __init__( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.services = {} # type: Dict[str, DNSRecord] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.next_time = current_time_millis() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.delay = delay | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._handlers_to_call = [] # type: List[Callable[[Zeroconf], None]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._handlers_to_call = OrderedDict() # type: OrderedDict[str, ServiceStateChange] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._service_state_changed = Signal() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1428,14 +1430,30 @@ def service_state_changed(self) -> SignalRegistrationInterface: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| def update_record(self, zc: 'Zeroconf', now: float, record: DNSRecord) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Callback invoked by Zeroconf when new information arrives. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Updates information required by browser in the Zeroconf cache.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Updates information required by browser in the Zeroconf cache. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ensures that there is are no unecessary duplicates in the list | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def enqueue_callback(state_change: ServiceStateChange, name: str) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._handlers_to_call.append( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lambda zeroconf: self._service_state_changed.fire( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zeroconf=zeroconf, service_type=self.type, name=name, state_change=state_change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, two things here. Regarding the logic, I had to write myself a little table to make sure I understand things correctly. I added some notes in two cases that I believe to be worth taking a second look at. The table:
Regarding the implementation details, I think if (
(state_change is ServiceStateChange.Updated and name not in self._handlers_to_call)
or (
state_change is ServiceStateChange.Removed
and self._handlers_to_call.get(name) is ServiceStateChange.Updated
)
or state_change is ServiceStateChange.Added
):
self._handlers_to_call[name] = state_changeThis removes all that
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about it, the code could just be an unconditional
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ll have a bit more of a think about this one the coming week.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your last suggestion won't work because then an update trumps an add. I've used a slightly amended version of your first suggestion and the code you had above didn't update removed if for example the list was empty. Regarding your 2 queries about the truth table, yes there are some combinations that don't make sense and in a well written responded shouldn't happen. However I've taken the view that I need to make a decision on the precedence of the messages and my view is that Added always wins, so for example if we receive an add and remove message in the same batch, then add is the most likely meaning. I can hypothesise a reason this might occur if you have multiple res ponders and one goes offline. In this case Added + Removed still means there is a service there to respond. (note this is a contrived example as the messages would come in a different batch)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough – if it causes issues I expect it'll be reported and we'll sort it out then, having a concrete case to deal with. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Code to ensure we only do a single update message | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Precedence is; Added, Remove, Update | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state_change is ServiceStateChange.Added | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| or ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state_change is ServiceStateChange.Removed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._handlers_to_call.get(name) is ServiceStateChange.Updated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| or self._handlers_to_call.get(name) is ServiceStateChange.Added | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| or self._handlers_to_call.get(name) is None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| or (state_change is ServiceStateChange.Updated and name not in self._handlers_to_call) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._handlers_to_call[name] = state_change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if record.type == _TYPE_PTR and record.name == self.type: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert isinstance(record, DNSPointer) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1459,8 +1477,20 @@ def enqueue_callback(state_change: ServiceStateChange, name: str) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| if expires < self.next_time: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.next_time = expires | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif record.type == _TYPE_TXT and record.name.endswith(self.type): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert isinstance(record, DNSText) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif record.type == _TYPE_A or record.type == _TYPE_AAAA: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert isinstance(record, DNSAddress) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Iterate through the DNSCache and callback any services that use this address | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for service in zc.cache.entries(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isinstance(service, DNSService) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and service.name.endswith(self.type) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and service.server == record.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and not record.is_expired(now) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enqueue_callback(ServiceStateChange.Updated, service.name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif record.name.endswith(self.type): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expired = record.is_expired(now) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not expired: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enqueue_callback(ServiceStateChange.Updated, record.name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1492,8 +1522,11 @@ def run(self) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.delay = min(_BROWSER_BACKOFF_LIMIT * 1000, self.delay * 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(self._handlers_to_call) > 0 and not self.zc.done: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handler = self._handlers_to_call.pop(0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handler(self.zc) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with self.zc._handlers_lock: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handler = self._handlers_to_call.popitem(False) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._service_state_changed.fire( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zeroconf=self.zc, service_type=self.type, name=handler[0], state_change=handler[1] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class ServiceInfo(RecordUpdateListener): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -2156,6 +2189,8 @@ def __init__( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.debug = None # type: Optional[DNSOutgoing] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._handlers_lock = threading.Lock() # ensure we process a full message in one go | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def done(self) -> bool: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self._GLOBAL_DONE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -2432,42 +2467,45 @@ def update_record(self, now: float, rec: DNSRecord) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| def handle_response(self, msg: DNSIncoming) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Deal with incoming response packets. All answers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| are held in the cache, and listeners are notified.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| now = current_time_millis() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for record in msg.answers: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updated = True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if record.unique: # https://tools.ietf.org/html/rfc6762#section-10.2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Since the cache format is keyed on the lower case record name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # we can avoid iterating everything in the cache and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # only look though entries for the specific name. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # entries_with_name will take care of converting to lowercase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We make a copy of the list that entries_with_name returns | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # since we cannot iterate over something we might remove | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for entry in self.cache.entries_with_name(record.name).copy(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if entry == record: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updated = False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with self._handlers_lock: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check the time first because it is far cheaper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # than the __eq__ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (record.created - entry.created > 1000) and DNSEntry.__eq__(entry, record): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.remove(entry) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expired = record.is_expired(now) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maybe_entry = self.cache.get(record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not expired: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if maybe_entry is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maybe_entry.reset_ttl(record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| now = current_time_millis() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for record in msg.answers: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updated = True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if record.unique: # https://tools.ietf.org/html/rfc6762#section-10.2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Since the cache format is keyed on the lower case record name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # we can avoid iterating everything in the cache and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # only look though entries for the specific name. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # entries_with_name will take care of converting to lowercase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We make a copy of the list that entries_with_name returns | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # since we cannot iterate over something we might remove | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for entry in self.cache.entries_with_name(record.name).copy(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if entry == record: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updated = False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check the time first because it is far cheaper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # than the __eq__ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (record.created - entry.created > 1000) and DNSEntry.__eq__(entry, record): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.remove(entry) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expired = record.is_expired(now) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maybe_entry = self.cache.get(record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not expired: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if maybe_entry is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maybe_entry.reset_ttl(record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.add(record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if updated: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.update_record(now, record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.add(record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if updated: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.update_record(now, record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if maybe_entry is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.update_record(now, record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.remove(maybe_entry) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if maybe_entry is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.update_record(now, record) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.cache.remove(maybe_entry) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def handle_query(self, msg: DNSIncoming, addr: Optional[str], port: int) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Deal with incoming query packets. Provides a response if | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.