flubshi / python-zeroconf

A pure python implementation of multicast DNS service discovery

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

python-zeroconf

image

image

image

Documentation.

This is fork of pyzeroconf, Multicast DNS Service Discovery for Python, originally by Paul Scott-Murphy (https://github.com/paulsm/pyzeroconf), modified by William McBrine (https://github.com/wmcbrine/pyzeroconf).

The original William McBrine's fork note:

This fork is used in all of my TiVo-related projects: HME for Python
(and therefore HME/VLC), Network Remote, Remote Proxy, and pyTivo.
Before this, I was tracking the changes for zeroconf.py in three
separate repos. I figured I should have an authoritative source.

Although I make changes based on my experience with TiVos, I expect that
they're generally applicable. This version also includes patches found
on the now-defunct (?) Launchpad repo of pyzeroconf, and elsewhere
around the net -- not always well-documented, sorry.

Compatible with:

  • Bonjour
  • Avahi

Compared to some other Zeroconf/Bonjour/Avahi Python packages, python-zeroconf:

  • isn't tied to Bonjour or Avahi
  • doesn't use D-Bus
  • doesn't force you to use particular event loop or Twisted (asyncio is used under the hood but not required)
  • is pip-installable
  • has PyPI distribution

Python compatibility

  • CPython 3.6+
  • PyPy3 7.2+

Versioning

This project's versions follow the following pattern: MAJOR.MINOR.PATCH.

  • MAJOR version has been 0 so far
  • MINOR version is incremented on backward incompatible changes
  • PATCH version is incremented on backward compatible changes

Status

This project is actively maintained.

Traffic Reduction

Before version 0.32, most traffic reduction techniques described in https://datatracker.ietf.org/doc/html/rfc6762#section-7 where not implemented which could lead to excessive network traffic. It is highly recommended that version 0.32 or later is used if this is a concern.

IPv6 support

IPv6 support is relatively new and currently limited, specifically:

  • InterfaceChoice.All is an alias for InterfaceChoice.Default on non-POSIX systems.
  • On Windows specific interfaces can only be requested as interface indexes, not as IP addresses.
  • Dual-stack IPv6 sockets are used, which may not be supported everywhere (some BSD variants do not have them).
  • Listening on localhost (::1) does not work. Help with understanding why is appreciated.

How to get python-zeroconf?

The easiest way to install python-zeroconf is using pip:

pip install zeroconf

How do I use it?

Here's an example of browsing for a service:

from zeroconf import ServiceBrowser, Zeroconf


class MyListener:

    def remove_service(self, zeroconf, type, name):
        print("Service %s removed" % (name,))

    def add_service(self, zeroconf, type, name):
        info = zeroconf.get_service_info(type, name)
        print("Service %s added, service info: %s" % (name, info))


zeroconf = Zeroconf()
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
try:
    input("Press enter to exit...\n\n")
finally:
    zeroconf.close()

Note

Discovery and service registration use all available network interfaces by default. If you want to customize that you need to specify interfaces argument when constructing Zeroconf object (see the code for details).

If you don't know the name of the service you need to browse for, try:

from zeroconf import ZeroconfServiceTypes
print('\n'.join(ZeroconfServiceTypes.find()))

See examples directory for more.

Changelog

0.32.0 Beta 4

  • Simplify wait_event_or_timeout (#810) @bdraco

    This function always did the same thing on timeout and wait complete so we can use the same callback. This solves the CI failing due to the test coverage flapping back and forth as the timeout would rarely happen.

  • Make DNSHinfo and DNSAddress use the same match order as DNSPointer and DNSText (#808) @bdraco

    We want to check the data that is most likely to be unique first so we can reject the __eq__ as soon as possible.

  • Qualify IPv6 link-local addresses with scope_id (#343) @ibygrave

    When a service is advertised on an IPv6 address where the scope is link local, i.e. fe80::/64 (see RFC 4007) the resolved IPv6 address must be extended with the scope_id that identifies through the "%" symbol the local interface to be used when routing to that address. A new API parsed_scoped_addresses() is provided to return qualified addresses to avoid breaking compatibility on the existing parsed_addresses().

0.32.0 Beta 3

  • Skip network adapters that are disconnected (#327) @ZLJasonG
  • Add slots to DNS classes (#803) @bdraco

    On a busy network that receives many mDNS packets per second, we will not know the answer to most of the questions being asked. In this case the creating the DNS* objects are usually garbage collected within 1s as they are not needed. We now set __slots__ to speed up the creation and destruction of these objects

0.32.0 Beta 2

  • Ensure we handle threadsafe shutdown under PyPy with multiple event loops (#800) @bdraco
  • Ensure fresh ServiceBrowsers see old_record as None when replaying the cache (#793) @bdraco

    This is fixing ServiceBrowser missing an add when the record is already in the cache.

  • Pass both the new and old records to async_update_records (#792) @bdraco

    Pass the old_record (cached) as the value and the new_record (wire) to async_update_records instead of forcing each consumer to check the cache since we will always have the old_record when generating the async_update_records call. This avoids the overhead of multiple cache lookups for each listener.

  • Make add_listener and remove_listener threadsafe (#794) @bdraco
  • Ensure outgoing ServiceBrowser questions are seen by the question history (#790) @bdraco

0.32.0 Beta 1

Documentation for breaking changes era on the side of the caution and likely overstates the risk on many of these. If you are not accessing zeroconf internals, you can likely not be concerned with the breaking changes below:

  • BREAKING CHANGE: zeroconf.asyncio has been renamed zeroconf.aio (#503) @bdraco

    The asyncio name could shadow system asyncio in some cases. If zeroconf is in sys.path, this would result in loading zeroconf.asyncio when system asyncio was intended.

  • BREAKING CHANGE: Update internal version check to match docs (3.6+) (#491) @bdraco

    Python version eariler then 3.6 were likely broken with zeroconf already, however the version is now explictly checked.

  • BREAKING CHANGE: RecordUpdateListener now uses async_update_records instead of update_record (#419, #726) @bdraco

    This allows the listener to receive all the records that have been updated in a single transaction such as a packet or cache expiry.

    update_record has been deprecated in favor of async_update_records A compatibility shim exists to ensure classes that use RecordUpdateListener as a base class continue to have update_record called, however they should be updated as soon as possible.

    A new method async_update_records_complete is now called on each listener when all listeners have completed processing updates and the cache has been updated. This allows ServiceBrowsers to delay calling handlers until they are sure the cache has been updated as its a common pattern to call for ServiceInfo when a ServiceBrowser handler fires.

    The async prefix was choosen to make it clear that these functions run in the eventloop and should never do blocking I/O. Before 0.32+ these functions ran in a select() loop and should not have been doing any blocking I/O, but it was not clear to implementors that I/O would block the loop.

  • BREAKING CHANGE: Ensure listeners do not miss initial packets if Engine starts too quickly (#387) @bdraco

    When manually creating a zeroconf.Engine object, it is no longer started automatically. It must manually be started by calling .start() on the created object.

    The Engine thread is now started after all the listeners have been added to avoid a race condition where packets could be missed at startup.

  • BREAKING CHANGE: Remove DNSOutgoing.packet backwards compatibility (#569) @bdraco

    DNSOutgoing.packet only returned a partial message when the DNSOutgoing contents exceeded _MAX_MSG_ABSOLUTE or _MAX_MSG_TYPICAL This was a legacy function that was replaced with .packets() which always returns a complete payload in #248 As packet() should not be used since it will end up missing data, it has been removed

  • BREAKING CHANGE: Mark DNSOutgoing write functions as protected (#633) @bdraco

    These functions are not intended to be used by external callers and the API is not likely to be stable in the future

  • BREAKING CHANGE: Prefix cache functions that are non threadsafe with async (#724) @bdraco

    Adding (zc.cache.add -> zc.cache.async_add_records), removing (zc.cache.remove -> zc.cache.async_remove_records), and expiring the cache (zc.cache.expire -> zc.cache.async_expire) the cache is not threadsafe and must be called from the event loop (previously the Engine select loop before 0.32)

    These functions should only be run from the event loop as they are NOT thread safe.

    We never expect these functions will be called externally, however it was possible so this is documented as a breaking change. It is highly recommended that external callers do not modify the cache directly.

  • TRAFFIC REDUCTION: Add support for handling QU questions (#621) @bdraco

    Implements RFC 6762 sec 5.4: Questions Requesting Unicast Responses datatracker.ietf.org/doc/html/rfc6762#section-5.4

  • TRAFFIC REDUCTION: Protect the network against excessive packet flooding (#619) @bdraco
  • TRAFFIC REDUCTION: Suppress additionals when they are already in the answers section (#617) @bdraco
  • TRAFFIC REDUCTION: Avoid including additionals when the answer is suppressed by known-answer supression (#614) @bdraco
  • TRAFFIC REDUCTION: Implement multi-packet known answer supression (#687) @bdraco

    Implements datatracker.ietf.org/doc/html/rfc6762#section-7.2

  • TRAFFIC REDUCTION: Efficiently bucket queries with known answers (#698) @bdraco
  • TRAFFIC REDUCTION: Implement duplicate question supression (#770) @bdraco

    http://datatracker.ietf.org/doc/html/rfc6762#section-7.3

  • MAJOR BUG: Ensure matching PTR queries are returned with the ANY query (#618) @bdraco
  • MAJOR BUG: Fix lookup of uppercase names in registry (#597) @bdraco

    If the ServiceInfo was registered with an uppercase name and the query was for a lowercase name, it would not be found and vice-versa.

  • MAJOR BUG: Ensure unicast responses can be sent to any source port (#598) @bdraco

    Unicast responses were only being sent if the source port was 53, this prevented responses when testing with dig:

    dig -p 5353 @224.0.0.251 media-12.local

    The above query will now see a response

  • MAJOR BUG: Fix queries for AAAA records (#616) @bdraco
  • Add async_apple_scanner example (#719) @bdraco
  • Add support for requesting QU questions to ServiceBrowser and ServiceInfo (#787) @bdraco
  • Ensure the queue is created before adding listeners to ServiceBrowser (#785) @bdraco

    The callback from the listener could generate an event that would fire in async context that should have gone to the queue which could result in the consumer running a sync call in the event loop and blocking it.

  • Add a guard to prevent running ServiceInfo.request in async context (#784) @bdraco
  • Inline utf8 decoding when processing incoming packets (#782) @bdraco
  • Drop utf cache from _dns (#781) (later reverted) @bdraco
  • Switch to using a simple cache instead of lru_cache (#779) (later reverted) @bdraco
  • Fix Responding to Address Queries (RFC6762 section 6.2) (#777) @bdraco
  • Fix deadlock on ServiceBrowser shutdown with PyPy (#774) @bdraco
  • Add a guard against the task list changing when shutting down (#776) @bdraco
  • Improve performance of parsing DNSIncoming by caching read_utf (#769) (later reverted) @bdraco
  • Switch to using an asyncio.Event for async_wait (#759) @bdraco

    We no longer need to check for thread safety under a asyncio.Condition as the ServiceBrowser and ServiceInfo internals schedule coroutines in the eventloop.

  • Simplify ServiceBrowser callsbacks (#756) @bdraco
  • Revert: Fix thread safety in _ServiceBrowser.update_records_complete (#708) (#755) @bdraco
  • This guarding is no longer needed as the ServiceBrowser loop now runs in the event loop and the thread safety guard is no longer needed
  • Drop AsyncServiceListener (#754) @bdraco (Never shipped)
  • Run ServiceBrowser queries in the event loop (#752) @bdraco
  • Remove unused argument from AsyncZeroconf (#751) @bdraco
  • Fix warning about Zeroconf._async_notify_all not being awaited in sync shutdown (#750) @bdraco
  • Update async_service_info_request example to ensure it runs in the right event loop (#749) @bdraco
  • Run ServiceInfo requests in the event loop (#748) @bdraco
  • Remove support for notify listeners (#733) @bdraco (Never shipped)
  • Relocate service browser tests to tests/services/test_browser.py (#745) @bdraco
  • Relocate ServiceInfo to zeroconf._services.info (#741) @bdraco
  • Run question answer callbacks from add_listener in the event loop (#740) @bdraco

    Calling async_update_records and async_update_records_complete should always happen in the event loop to ensure implementers do not need to worry about thread safety

  • Remove second level caching from ServiceBrowsers (#737) @bdraco

    The ServiceBrowser had its own cache of the last time it saw a service which was reimplementing the DNSCache and presenting a source of truth problem that lead to unexpected queries when the two disagreed.

  • Breakout ServiceBrowser handler from listener creation (#736) @bdraco

    Add coverage for the handler from listener

  • Add fast cache lookup functions (#732) @bdraco

    The majority of our lookups happen in the event loop so there is no need for them to be threadsafe. Now that the codebase is more clear about what needs to be threadsafe and what does not need to be threadsafe we can use the much faster non-threadsafe versions in the places where we are calling from the event loop.

  • Switch to using DNSRRSet in RecordManager (#735) @bdraco

    DNSRRSet is able to do O(1) lookups of records assuming there are no collisions.

  • Fix server cache to be case-insensitive (#731) @bdraco

    If the server name had uppercase chars and any of the matching records were lowercase, the server would not be found

  • Fix cache handling of records with different TTLs (#729) @bdraco

    There should only be one unique record in the cache at a time as having multiple unique records will different TTLs in the cache can result in unexpected behavior since some functions returned all matching records and some fetched from the right side of the list to return the newest record. Intead we now store the records in a dict to ensure that the newest record always replaces the same unique record and we never have a source of truth problem determining the TTL of a record from the cache.

  • Rename handlers and internals to make it clear what is threadsafe (#726) @bdraco

    It was too easy to get confused about what was threadsafe and what was not threadsafe which lead to unexpected failures. Rename functions to make it clear what will be run in the event loop and what is expected to be threadsafe

  • Fix ServiceInfo with multiple A records (#725) @bdraco

    If there were multiple A records for the host, ServiceInfo would always return the last one that was in the incoming packet which was usually not the one that was wanted.

  • Synchronize time for fate sharing (#718) @bdraco
  • Cleanup typing in zero._core and document ignores (#714) @bdraco
  • Cleanup typing in zeroconf._logger (#715) @bdraco
  • Cleanup typing in zeroconf._utils.net (#713) @bdraco
  • Cleanup typing in zeroconf._services (#711) @bdraco
  • Cleanup typing in zeroconf._services.registry (#712) @bdraco
  • Add setter for DNSQuestion to easily make a QU question (#710) @bdraco
  • Set stale unique records to expire 1s in the future instead of instant removal (#706) @bdraco

    tools.ietf.org/html/rfc6762#section-10.2 Queriers receiving a Multicast DNS response with a TTL of zero SHOULD NOT immediately delete the record from the cache, but instead record a TTL of 1 and then delete the record one second later. In the case of multiple Multicast DNS responders on the network described in Section 6.6 above, if one of the responders shuts down and incorrectly sends goodbye packets for its records, it gives the other cooperating responders one second to send out their own response to "rescue" the records before they expire and are deleted.

  • Fix thread safety in _ServiceBrowser.update_records_complete (#708) @bdraco
  • Split DNSOutgoing/DNSIncoming/DNSMessage into zeroconf._protocol (#705) @bdraco
  • Abstract DNSOutgoing ttl write into _write_ttl (#695) @bdraco
  • Rollback data in one call instead of poping one byte at a time in DNS Outgoing (#696) @bdraco
  • Suppress additionals when answer is suppressed (#690) @bdraco
  • Move setting DNS created and ttl into its own function (#692) @bdraco
  • Add truncated property to DNSMessage to lookup the TC bit (#686) @bdraco
  • Check if SO_REUSEPORT exists instead of using an exception catch (#682) @bdraco
  • Use DNSRRSet for known answer suppression (#680) @bdraco

    DNSRRSet uses hash table lookups under the hood which is much faster than the linear searches used by DNSRecord.suppressed_by

  • Add DNSRRSet class for quick hashtable lookups of records (#678) @bdraco

    This class will be used to do fast checks to see if records should be suppressed by a set of answers.

  • Allow unregistering a service multiple times (#679) @bdraco
  • Remove unreachable BadTypeInNameException check in _ServiceBrowser (#677) @bdraco
  • Update async_browser.py example to use AsyncZeroconfServiceTypes (#665) @bdraco
  • Add an AsyncZeroconfServiceTypes to mirror ZeroconfServiceTypes to zeroconf.aio (#658) @bdraco
  • Remove all calls to the executor in AsyncZeroconf (#653) @bdraco
  • Set __all__ in zeroconf.aio to ensure private functions do now show in the docs (#652) @bdraco
  • Ensure interface_index_to_ip6_address skips ipv4 adapters (#651) @bdraco
  • Add async_unregister_all_services to AsyncZeroconf (#649) @bdraco
  • Ensure services are removed from the registry when calling unregister_all_services (#644) @bdraco

    There was a race condition where a query could be answered for a service in the registry while goodbye packets which could result a fresh record being broadcast after the goodbye if a query came in at just the right time. To avoid this, we now remove the services from the registry right after we generate the goodbye packet

  • Use ServiceInfo.key/ServiceInfo.server_key instead of lowering in ServiceRegistry (#647) @bdraco
  • Ensure the ServiceInfo.key gets updated when the name is changed externally (#645) @bdraco
  • Ensure AsyncZeroconf.async_close can be called multiple times like Zeroconf.close (#638) @bdraco
  • Ensure eventloop shutdown is threadsafe (#636) @bdraco
  • Return early in the shutdown/close process (#632) @bdraco
  • Remove unreachable cache check for DNSAddresses (#629) @bdraco

    The ServiceBrowser would check to see if a DNSAddress was already in the cache and return early to avoid sending updates when the address already was held in the cache. This check was not needed since there is already a check a few lines before as self.zc.cache.get(record) which effectively does the same thing. This lead to the check never being covered in the tests and 2 cache lookups when only one was needed.

  • Add test for wait_condition_or_timeout_times_out util (#630) @bdraco
  • Return early on invalid data received (#628) @bdraco

    Improve coverage for handling invalid incoming data

  • Add test to ensure ServiceBrowser sees port change as an update (#625) @bdraco
  • Fix random test failures due to monkey patching not being undone between tests (#626) @bdraco

    Switch patching to use unitest.mock.patch to ensure the patch is reverted when the test is completed

  • Ensure zeroconf can be loaded when the system disables IPv6 (#624) @bdraco
  • Eliminate aio sender thread (#622) @bdraco
  • Replace select loop with asyncio loop (#504) @bdraco
  • Add is_recent property to DNSRecord (#620) @bdraco

    RFC 6762 defines recent as not multicast within one quarter of its TTL datatracker.ietf.org/doc/html/rfc6762#section-5.4

  • Breakout the query response handler into its own class (#615) @bdraco
  • Add the ability for ServiceInfo.dns_addresses to filter by address type (#612) @bdraco
  • Make DNSRecords hashable (#611) @bdraco

    Allows storing them in a set for de-duplication

    Needed to be able to check for duplicates to solve #604

  • Ensure the QU bit is set for probe queries (#609) @bdraco

    The bit should be set per datatracker.ietf.org/doc/html/rfc6762#section-8.1

  • Log destination when sending packets (#606) @bdraco
  • Fix docs version to match readme (cpython 3.6+) (#602) @bdraco
  • Add ZeroconfServiceTypes to zeroconf.__all__ (#601) @bdraco

    This class is in the readme, but is not exported by default

  • Add id param to allow setting the id in the DNSOutgoing constructor (#599) @bdraco
  • Add unicast property to DNSQuestion to determine if the QU bit is set (#593) @bdraco
  • Reduce branching in DNSOutgoing.add_answer_at_time (#592) @bdraco
  • Breakout DNSCache into zeroconf.cache (#568) @bdraco
  • Removed protected imports from zeroconf namespace (#567) @bdraco
  • Fix invalid typing in ServiceInfo._set_text (#554) @bdraco
  • Move QueryHandler and RecordManager handlers into zeroconf.handlers (#551) @bdraco
  • Move ServiceListener to zeroconf.services (#550) @bdraco
  • Move the ServiceRegistry into its own module (#549) @bdraco
  • Move ServiceStateChange to zeroconf.services (#548) @bdraco
  • Relocate core functions into zeroconf.core (#547) @bdraco
  • Breakout service classes into zeroconf.services (#544) @bdraco
  • Move service_type_name to zeroconf.utils.name (#543) @bdraco
  • Relocate DNS classes to zeroconf.dns (#541) @bdraco
  • Update zeroconf.aio import locations (#539) @bdraco
  • Move int2byte to zeroconf.utils.struct (#540) @bdraco
  • Breakout network utils into zeroconf.utils.net (#537) @bdraco
  • Move time utility functions into zeroconf.utils.time (#536) @bdraco
  • Avoid making DNSOutgoing aware of the Zeroconf object (#535) @bdraco
  • Move logger into zeroconf.logger (#533) @bdraco
  • Move exceptions into zeroconf.exceptions (#532) @bdraco
  • Move constants into const.py (#531) @bdraco
  • Move asyncio utils into zeroconf.utils.aio (#530) @bdraco
  • Move ipversion auto detection code into its own function (#524) @bdraco
  • Breaking change: Update python compatibility as PyPy3 7.2 is required (#523) @bdraco
  • Remove broad exception catch from RecordManager.remove_listener (#517) @bdraco
  • Small cleanups to RecordManager.add_listener (#516) @bdraco
  • Move RecordUpdateListener management into RecordManager (#514) @bdraco
  • Break out record updating into RecordManager (#512) @bdraco
  • Remove uneeded wait in the Engine thread (#511) @bdraco
  • Extract code for handling queries into QueryHandler (#507) @bdraco
  • Set the TC bit for query packets where the known answers span multiple packets (#494) @bdraco
  • Ensure packets are properly seperated when exceeding maximum size (#498) @bdraco

    Ensure that questions that exceed the max packet size are moved to the next packet. This fixes DNSQuestions being sent in multiple packets in violation of: datatracker.ietf.org/doc/html/rfc6762#section-7.2

    Ensure only one resource record is sent when a record exceeds _MAX_MSG_TYPICAL datatracker.ietf.org/doc/html/rfc6762#section-17

  • Make a base class for DNSIncoming and DNSOutgoing (#497) @bdraco
  • Remove unused __ne__ code from Python 2 era (#492) @bdraco
  • Lint before testing in the CI (#488) @bdraco
  • Add AsyncServiceBrowser example (#487) @bdraco
  • Move threading daemon property into ServiceBrowser class (#486) @bdraco
  • Enable test_integration_with_listener_class test on PyPy (#485) @bdraco
  • AsyncServiceBrowser must recheck for handlers to call when holding condition (#483)

    There was a short race condition window where the AsyncServiceBrowser could add to _handlers_to_call in the Engine thread, have the condition notify_all called, but since the AsyncServiceBrowser was not yet holding the condition it would not know to stop waiting and process the handlers to call.

  • Relocate ServiceBrowser wait time calculation to seperate function (#484) @bdraco

    Eliminate the need to duplicate code between the ServiceBrowser and AsyncServiceBrowser to calculate the wait time.

  • Switch from using an asyncio.Event to asyncio.Condition for waiting (#482) @bdraco
  • ServiceBrowser must recheck for handlers to call when holding condition (#477) @bdraco

    There was a short race condition window where the ServiceBrowser could add to _handlers_to_call in the Engine thread, have the condition notify_all called, but since the ServiceBrowser was not yet holding the condition it would not know to stop waiting and process the handlers to call.

  • Provide a helper function to convert milliseconds to seconds (#481) @bdraco
  • Fix AsyncServiceInfo.async_request not waiting long enough (#480) @bdraco
  • Add support for updating multiple records at once to ServiceInfo (#474) @bdraco
  • Narrow exception catch in DNSAddress.__repr__ to only expected exceptions (#473) @bdraco
  • Add test coverage to ensure ServiceInfo rejects expired records (#468) @bdraco
  • Reduce branching in service_type_name (#472) @bdraco
  • Fix flakey test_update_record (#470) @bdraco
  • Reduce branching in Zeroconf.handle_response (#467) @bdraco
  • Ensure PTR questions asked in uppercase are answered (#465) @bdraco
  • Clear cache between ServiceTypesQuery tests (#466) @bdraco
  • Break apart Zeroconf.handle_query to reduce branching (#462) @bdraco
  • Support for context managers in Zeroconf and AsyncZeroconf (#284) @shenek
  • Use constant for service type enumeration (#461) @bdraco
  • Reduce branching in Zeroconf.handle_response (#459) @bdraco
  • Reduce branching in Zeroconf.handle_query (#460) @bdraco
  • Enable pylint (#438) @bdraco
  • Trap OSError directly in Zeroconf.send instead of checking isinstance (#453) @bdraco
  • Disable protected-access on the ServiceBrowser usage of _handlers_lock (#452) @bdraco
  • Mark functions with too many branches in need of refactoring (#455) @bdraco
  • Disable pylint no-self-use check on abstract methods (#451) @bdraco
  • Use unique name in test_async_service_browser test (#450) @bdraco
  • Disable no-member check for WSAEINVAL false positive (#454) @bdraco
  • Mark methods used by asyncio without self use (#447) @bdraco
  • Extract _get_queue from zeroconf.asyncio._AsyncSender (#444) @bdraco
  • Fix redefining argument with the local name 'record' in ServiceInfo.update_record (#448) @bdraco
  • Remove unneeded-not in new_socket (#445) @bdraco
  • Disable broad except checks in places we still catch broad exceptions (#443) @bdraco
  • Merge _TYPE_CNAME and _TYPE_PTR comparison in DNSIncoming.read_others (#442) @bdraco
  • Convert unnecessary use of a comprehension to a list (#441) @bdraco
  • Remove unused now argument from ServiceInfo._process_record (#440) @bdraco
  • Disable pylint too-many-branches for functions that need refactoring (#439) @bdraco
  • Cleanup unused variables (#437) @bdraco
  • Cleanup unnecessary else after returns (#436) @bdraco
  • Add zeroconf.asyncio to the docs (#434) @bdraco
  • Fix warning when generating sphinx docs (#432) @bdraco
  • Implement an AsyncServiceBrowser to compliment the sync ServiceBrowser (#429) @bdraco
  • Seperate non-thread specific code from ServiceBrowser into _ServiceBrowserBase (#428) @bdraco
  • Remove is_type_unique as it is unused (#426)
  • Avoid checking the registry when answering requests for _services._dns-sd._udp.local. (#425) @bdraco

    _services._dns-sd._udp.local. is a special case and should never be in the registry

  • Remove unused argument from ServiceInfo.dns_addresses (#423) @bdraco
  • Add methods to generate DNSRecords from ServiceInfo (#422) @bdraco
  • Seperate logic for consuming records in ServiceInfo (#421) @bdraco
  • Seperate query generation for ServiceBrowser (#420) @bdraco
  • Add async_request example with browse (#415) @bdraco
  • Add async_register_service/async_unregister_service example (#414) @bdraco
  • Add async_get_service_info to AsyncZeroconf and async_request to AsyncServiceInfo (#408) @bdraco
  • Add support for registering notify listeners (#409) @bdraco
  • Allow passing in a sync Zeroconf instance to AsyncZeroconf (#406) @bdraco
  • Use a dedicated thread for sending outgoing packets with asyncio (#404) @bdraco
  • Fix IPv6 setup under MacOS when binding to "" (#392) @bdraco
  • Ensure ZeroconfServiceTypes.find always cancels the ServiceBrowser (#389) @bdraco

    There was a short window where the ServiceBrowser thread could be left running after Zeroconf is closed because the .join() was never waited for when a new Zeroconf object was created

  • Simplify DNSPointer processing in ServiceBrowser (#386) @bdraco
  • Ensure the cache is checked for name conflict after final service query with asyncio (#382) @bdraco
  • Complete ServiceInfo request as soon as all questions are answered (#380) @bdraco

    Closes a small race condition where there were no questions to ask because the cache was populated in between checks

  • Coalesce browser questions scheduled at the same time (#379) @bdraco
  • Ensure duplicate packets do not trigger duplicate updates (#376) @bdraco

    If TXT or SRV records update was already processed and then recieved again, it was possible for a second update to be called back in the ServiceBrowser

  • Only trigger a ServiceStateChange.Updated event when an ip address is added (#375) @bdraco
  • Fix RFC6762 Section 10.2 paragraph 2 compliance (#374) @bdraco
  • Reduce length of ServiceBrowser thread name with many types (#373) @bdraco
  • Remove Callable quoting (#371) @bdraco
  • Abstract check to see if a record matches a type the ServiceBrowser wants (#369) @bdraco
  • Reduce complexity of ServiceBrowser enqueue_callback (#368) @bdraco
  • Fix empty answers being added in ServiceInfo.request (#367) @bdraco
  • Ensure ServiceInfo populates all AAAA records (#366) @bdraco

    Use get_all_by_details to ensure all records are loaded into addresses.

    Only load A/AAAA records from cache once in load_from_cache if there is a SRV record present

    Move duplicate code that checked if the ServiceInfo was complete into its own function

  • Remove black python 3.5 exception block (#365) @bdraco
  • Small cleanup of ServiceInfo.update_record (#364) @bdraco
  • Add new cache function get_all_by_details (#363) @bdraco When working with IPv6, multiple AAAA records can exist for a given host. get_by_details would only return the latest record in the cache.

    Fix a case where the cache list can change during iteration

  • Small cleanups to asyncio tests (#362) @bdraco
  • Improve test coverage for name conflicts (#357) @bdraco
  • Return task objects created by AsyncZeroconf (#360) @nocarryr

0.31.0

  • Separated cache loading from I/O in ServiceInfo and fixed cache lookup (#356), thanks to J. Nick Koston.

    The ServiceInfo class gained a load_from_cache() method to only fetch information from Zeroconf cache (if it exists) with no IO performed. Additionally this should reduce IO in cases where cache lookups were previously incorrectly failing.

0.30.0

  • Some nice refactoring work including removal of the Reaper thread, thanks to J. Nick Koston.
  • Fixed a Windows-specific The requested address is not valid in its context regression, thanks to Timothee ‘TTimo’ Besset and J. Nick Koston.
  • Provided an asyncio-compatible service registration layer (in the zeroconf.asyncio module), thanks to J. Nick Koston.

0.29.0

  • A single socket is used for listening on responding when InterfaceChoice.Default is chosen. Thanks to J. Nick Koston.

Backwards incompatible:

  • Dropped Python 3.5 support

0.28.8

  • Fixed the packet generation when multiple packets are necessary, previously invalid packets were generated sometimes. Patch thanks to J. Nick Koston.

0.28.7

  • Fixed the IPv6 address rendering in the browser example, thanks to Alexey Vazhnov.
  • Fixed a crash happening when a service is added or removed during handle_response and improved exception handling, thanks to J. Nick Koston.

0.28.6

  • Loosened service name validation when receiving from the network this lets us handle some real world devices previously causing errors, thanks to J. Nick Koston.

0.28.5

  • Enabled ignoring duplicated messages which decreases CPU usage, thanks to J. Nick Koston.
  • Fixed spurious AttributeError: module 'unittest' has no attribute 'mock' in tests.

0.28.4

  • Improved cache reaper performance significantly, thanks to J. Nick Koston.
  • Added ServiceListener to __all__ as it's part of the public API, thanks to Justin Nesselrotte.

0.28.3

  • Reduced a time an internal lock is held which should eliminate deadlocks in high-traffic networks, thanks to J. Nick Koston.

0.28.2

  • Stopped asking questions we already have answers for in cache, thanks to Paul Daumlechner.
  • Removed initial delay before querying for service info, thanks to Erik Montnemery.

0.28.1

  • Fixed a resource leak connected to using ServiceBrowser with multiple types, thanks to
    1. Nick Koston.

0.28.0

  • Improved Windows support when using socket errno checks, thanks to Sandy Patterson.
  • Added support for passing text addresses to ServiceInfo.
  • Improved logging (includes fixing an incorrect logging call)
  • Improved Windows compatibility by using Adapter.index from ifaddr, thanks to PhilippSelenium.
  • Improved Windows compatibility by stopping using socket.if_nameindex.
  • Fixed an OS X edge case which should also eliminate a memory leak, thanks to Emil Styrke.

Technically backwards incompatible:

  • ifaddr 0.1.7 or newer is required now.

0.27.1

  • Improved the logging situation (includes fixing a false-positive "packets() made no progress adding records", thanks to Greg Badros)

0.27.0

  • Large multi-resource responses are now split into separate packets which fixes a bad mdns-repeater/ChromeCast Audio interaction ending with ChromeCast Audio crash (and possibly some others) and improves RFC 6762 compliance, thanks to Greg Badros
  • Added a warning presented when the listener passed to ServiceBrowser lacks update_service() callback
  • Added support for finding all services available in the browser example, thanks to Perry Kunder

Backwards incompatible:

  • Removed previously deprecated ServiceInfo address constructor parameter and property

0.26.3

  • Improved readability of logged incoming data, thanks to Erik Montnemery
  • Threads are given unique names now to aid debugging, thanks to Erik Montnemery
  • Fixed a regression where get_service_info() called within a listener add_service method would deadlock, timeout and incorrectly return None, fix thanks to Erik Montnemery, but Matt Saxon and Hmmbob were also involved in debugging it.

0.26.2

  • Added support for multiple types to ServiceBrowser, thanks to J. Nick Koston
  • Fixed a race condition where a listener gets a message before the lock is created, thanks to
    1. Nick Koston

0.26.1

  • Fixed a performance regression introduced in 0.26.0, thanks to J. Nick Koston (this is close in spirit to an optimization made in 0.24.5 by the same author)

0.26.0

  • Fixed a regression where service update listener wasn't called on IP address change (it's called on SRV/A/AAAA record changes now), thanks to Matt Saxon

Technically backwards incompatible:

  • Service update hook is no longer called on service addition (service added hook is still called), this is related to the fix above

0.25.1

  • Eliminated 5s hangup when calling Zeroconf.close(), thanks to Erik Montnemery

0.25.0

  • Reverted uniqueness assertions when browsing, they caused a regression

Backwards incompatible:

  • Rationalized handling of TXT records. Non-bytes values are converted to str and encoded to bytes using UTF-8 now, None values mean value-less attributes. When receiving TXT records no decoding is performed now, keys are always bytes and values are either bytes or None in value-less attributes.

0.24.5

  • Fixed issues with shared records being used where they shouldn't be (TXT, SRV, A records are unique now), thanks to Matt Saxon
  • Stopped unnecessarily excluding host-only interfaces from InterfaceChoice.all as they don't forbid multicast, thanks to Andreas Oberritter
  • Fixed repr() of IPv6 DNSAddress, thanks to Aldo Hoeben
  • Removed duplicate update messages sent to listeners, thanks to Matt Saxon
  • Added support for cooperating responders, thanks to Matt Saxon
  • Optimized handle_response cache check, thanks to J. Nick Koston
  • Fixed memory leak in DNSCache, thanks to J. Nick Koston

0.24.4

  • Fixed resetting TTL in DNSRecord.reset_ttl(), thanks to Matt Saxon
  • Improved various DNS class' string representations, thanks to Jay Hogg

0.24.3

  • Fixed import-time "TypeError: 'ellipsis' object is not iterable." on CPython 3.5.2

0.24.2

  • Added support for AWDL interface on macOS (needed and used by the opendrop project but should be useful in general), thanks to Milan Stute
  • Added missing type hints

0.24.1

  • Applied some significant performance optimizations, thanks to Jaime van Kessel for the patch and to Ghostkeeper for performance measurements
  • Fixed flushing outdated cache entries when incoming record is unique, thanks to Michael Hu
  • Fixed handling updates of TXT records (they'd not get recorded previously), thanks to Michael Hu

0.24.0

  • Added IPv6 support, thanks to Dmitry Tantsur
  • Added additional recommended records to PTR responses, thanks to Scott Mertz
  • Added handling of ENOTCONN being raised during shutdown when using Eventlet, thanks to Tamás Nepusz
  • Included the py.typed marker in the package so that type checkers know to use type hints from the source code, thanks to Dmitry Tantsur

0.23.0

  • Added support for MyListener call getting updates to service TXT records, thanks to Matt Saxon
  • Added support for multiple addresses when publishing a service, getting/setting single address has become deprecated. Change thanks to Dmitry Tantsur

Backwards incompatible:

  • Dropped Python 3.4 support

0.22.0

  • A lot of maintenance work (tooling, typing coverage and improvements, spelling) done, thanks to Ville Skyttä
  • Provided saner defaults in ServiceInfo's constructor, thanks to Jorge Miranda
  • Fixed service removal packets not being sent on shutdown, thanks to Andrew Bonney
  • Added a way to define TTL-s through ServiceInfo contructor parameters, thanks to Andrew Bonney

Technically backwards incompatible:

  • Adjusted query intervals to match RFC 6762, thanks to Andrew Bonney
  • Made default TTL-s match RFC 6762, thanks to Andrew Bonney

0.21.3

  • This time really allowed incoming service names to contain underscores (patch released as part of 0.21.0 was defective)

0.21.2

  • Fixed import-time typing-related TypeError when older typing version is used

0.21.1

  • Fixed installation on Python 3.4 (we use typing now but there was no explicit dependency on it)

0.21.0

  • Added an error message when importing the package using unsupported Python version
  • Fixed TTL handling for published service
  • Implemented unicast support
  • Fixed WSL (Windows Subsystem for Linux) compatibility
  • Fixed occasional UnboundLocalError issue
  • Fixed UTF-8 multibyte name compression
  • Switched from netifaces to ifaddr (pure Python)
  • Allowed incoming service names to contain underscores

0.20.0

  • Dropped support for Python 2 (this includes PyPy) and 3.3
  • Fixed some class' equality operators
  • ServiceBrowser entries are being refreshed when 'stale' now
  • Cache returns new records first now instead of last

0.19.1

  • Allowed installation with netifaces >= 0.10.6 (a bug that was concerning us got fixed)

0.19.0

  • Technically backwards incompatible - restricted netifaces dependency version to work around a bug, see python-zeroconf#84 for details

0.18.0

  • Dropped Python 2.6 support
  • Improved error handling inside code executed when Zeroconf object is being closed

0.17.7

  • Better Handling of DNS Incoming Packets parsing exceptions
  • Many exceptions will now log a warning the first time they are seen
  • Catch and log sendto() errors
  • Fix/Implement duplicate name change
  • Fix overly strict name validation introduced in 0.17.6
  • Greatly improve handling of oversized packets including:
    • Implement name compression per RFC1035
    • Limit size of generated packets to 9000 bytes as per RFC6762
    • Better handle over sized incoming packets
  • Increased test coverage to 95%

0.17.6

  • Many improvements to address race conditions and exceptions during ZC() startup and shutdown, thanks to: morpav, veawor, justingiorgi, herczy, stephenrauch
  • Added more test coverage: strahlex, stephenrauch
  • Stephen Rauch contributed:
    • Speed up browser startup
    • Add ZeroconfServiceTypes() query class to discover all advertised service types
    • Add full validation for service names, types and subtypes
    • Fix for subtype browsing
    • Fix DNSHInfo support

0.17.5

  • Fixed OpenBSD compatibility, thanks to Alessio Sergi
  • Fixed race condition on ServiceBrowser startup, thanks to gbiddison
  • Fixed installation on some Python 3 systems, thanks to Per Sandström
  • Fixed "size change during iteration" bug on Python 3, thanks to gbiddison

0.17.4

  • Fixed support for Linux kernel versions < 3.9 (thanks to Giovanni Harting and Luckydonald, GitHub pull request #26)

0.17.3

  • Fixed DNSText repr on Python 3 (it'd crash when the text was longer than 10 bytes), thanks to Paulus Schoutsen for the patch, GitHub pull request #24

0.17.2

  • Fixed installation on Python 3.4.3+ (was failing because of enum34 dependency which fails to install on 3.4.3+, changed to depend on enum-compat instead; thanks to Michael Brennan for the original patch, GitHub pull request #22)

0.17.1

  • Fixed EADDRNOTAVAIL when attempting to use dummy network interfaces on Windows, thanks to daid

0.17.0

  • Added some Python dependencies so it's not zero-dependencies anymore
  • Improved exception handling (it'll be quieter now)
  • Messages are listened to and sent using all available network interfaces by default (configurable); thanks to Marcus Müller
  • Started using logging more freely
  • Fixed a bug with binary strings as property values being converted to False (python-zeroconf#10); thanks to Dr. Seuss
  • Added new ServiceBrowser event handler interface (see the examples)
  • PyPy3 now officially supported
  • Fixed ServiceInfo repr on Python 3, thanks to Yordan Miladinov

0.16.0

  • Set up Python logging and started using it
  • Cleaned up code style (includes migrating from camel case to snake case)

0.15.1

  • Fixed handling closed socket (GitHub #4)

0.15

  • Forked by Jakub Stasiak
  • Made Python 3 compatible
  • Added setup script, made installable by pip and uploaded to PyPI
  • Set up Travis build
  • Reformatted the code and moved files around
  • Stopped catching BaseException in several places, that could hide errors
  • Marked threads as daemonic, they won't keep application alive now

0.14

  • Fix for SOL_IP undefined on some systems - thanks Mike Erdely.
  • Cleaned up examples.
  • Lowercased module name.

0.13

  • Various minor changes; see git for details.
  • No longer compatible with Python 2.2. Only tested with 2.5-2.7.
  • Fork by William McBrine.

0.12

  • allow selection of binding interface
  • typo fix - Thanks A. M. Kuchlingi
  • removed all use of word 'Rendezvous' - this is an API change

0.11

  • correction to comments for addListener method
  • support for new record types seen from OS X
    • IPv6 address
    • hostinfo
  • ignore unknown DNS record types
  • fixes to name decoding
  • works alongside other processes using port 5353 (e.g. on Mac OS X)
  • tested against Mac OS X 10.3.2's mDNSResponder
  • corrections to removal of list entries for service browser

0.10

  • Jonathon Paisley contributed these corrections:
    • always multicast replies, even when query is unicast
    • correct a pointer encoding problem
    • can now write records in any order
    • traceback shown on failure
    • better TXT record parsing
    • server is now separate from name
    • can cancel a service browser
  • modified some unit tests to accommodate these changes

0.09

  • remove all records on service unregistration
  • fix DOS security problem with readName

0.08

  • changed licensing to LGPL

0.07

  • faster shutdown on engine
  • pointer encoding of outgoing names
  • ServiceBrowser now works
  • new unit tests

0.06

  • small improvements with unit tests
  • added defined exception types
  • new style objects
  • fixed hostname/interface problem
  • fixed socket timeout problem
  • fixed add_service_listener() typo bug
  • using select() for socket reads
  • tested on Debian unstable with Python 2.2.2

0.05

  • ensure case insensitivty on domain names
  • support for unicast DNS queries

0.04

  • added some unit tests
  • added __ne__ adjuncts where required
  • ensure names end in '.local.'
  • timeout on receiving socket for clean shutdown

License

LGPL, see COPYING file for details.

About

A pure python implementation of multicast DNS service discovery

License:GNU Lesser General Public License v2.1


Languages

Language:Python 99.7%Language:Makefile 0.3%