GitHub - longan-link/python-zeroconf: A pure python implementation of multicast DNS service discovery

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

There are some people using this package. I don't actively use it and as such any help I can offer with regard to any issues is very limited.

See examples directory for more.

  • 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 update_records instead of update_record (#419) @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 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 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.

  • 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

  • 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

  • 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

  • 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

  • LGPL, see COPYING file for details.