Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions examples/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import logging
import socket
import sys
from time import sleep
from time import sleep,strftime as now

from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf


def on_service_state_change(zeroconf, service_type, name, state_change):
print("Service %s of type %s state changed: %s" % (name, service_type, state_change))
print("%s Service %s of type %s: %s" % (now('%Y-%m-%d %H:%M:%S'),name, service_type, state_change))

if state_change is ServiceStateChange.Added:
info = zeroconf.get_service_info(service_type, name)
Expand All @@ -32,13 +32,16 @@ def on_service_state_change(zeroconf, service_type, name, state_change):

if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
if len(sys.argv) > 1:
assert sys.argv[1:] == ['--debug']
if '--debug' in sys.argv:
logging.getLogger('zeroconf').setLevel(logging.DEBUG)
del sys.argv[sys.argv.index('--debug')]

zeroconf = Zeroconf()
print("\nBrowsing services, press Ctrl-C to exit...\n")
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", handlers=[on_service_state_change])
service=(sys.argv[1] if len(sys.argv)>1 and sys.argv[1].endswith(('_tcp','_udp')) else "_http._tcp")+".local."
print("\nBrowsing for %s, press Ctrl-C to exit...\n" % service)
browser = ServiceBrowser(zeroconf,
service,
handlers=[on_service_state_change])

try:
while True:
Expand Down
17 changes: 10 additions & 7 deletions examples/old_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
import logging
import socket
import sys
from time import sleep
from time import sleep,strftime as now

from zeroconf import ServiceBrowser, Zeroconf


class MyListener(object):

def remove_service(self, zeroconf, type, name):
print("Service %s removed" % (name,))
print("%s Service %s removed" % (now('%Y-%m-%d %H:%M:%S'),name,))
print('\n')

def add_service(self, zeroconf, type, name):
print("Service %s added" % (name,))
print("%s Service %s added" % (now('%Y-%m-%d %H:%M:%S'),name,))
print(" Type is %s" % (type,))
info = zeroconf.get_service_info(type, name)
if info:
Expand All @@ -37,14 +37,17 @@ def add_service(self, zeroconf, type, name):

if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
if len(sys.argv) > 1:
assert sys.argv[1:] == ['--debug']
if '--debug' in sys.argv:
logging.getLogger('zeroconf').setLevel(logging.DEBUG)
del sys.argv[sys.argv.index('--debug')]

zeroconf = Zeroconf()
print("\nBrowsing services, press Ctrl-C to exit...\n")
service=(sys.argv[1] if len(sys.argv)>1 and sys.argv[1].endswith(('_tcp','_udp')) else "_http._tcp")+".local."
print("\nBrowsing for %s, press Ctrl-C to exit...\n" % service)
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
browser = ServiceBrowser(zeroconf,
service,
listener)
try:
while True:
sleep(0.1)
Expand Down
33 changes: 33 additions & 0 deletions examples/zcresolv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from __future__ import absolute_import, division, print_function, unicode_literals

""" Example of resolving local hosts"""
# a stripped down verssion of browser.py example
# zeroconf may have issues with ipv6 addresses and mixed case hostnames

import sys
from time import sleep

from zeroconf import DNSAddress, ServiceBrowser, ServiceStateChange, Zeroconf


def on_service_state_change(zeroconf, service_type, name, state_change):
if state_change is ServiceStateChange.Added:
zeroconf.get_service_info(service_type, name)

zeroconf = Zeroconf()
ServiceBrowser(zeroconf, "_workstation._tcp.local.", handlers=[on_service_state_change])
ServiceBrowser(zeroconf, "_telnet._tcp.local.", handlers=[on_service_state_change])
ServiceBrowser(zeroconf, "_http._tcp.local.", handlers=[on_service_state_change])
ServiceBrowser(zeroconf, "_printer._tcp.local.", handlers=[on_service_state_change])
sleep(2)
# lookup specific host
if len(sys.argv) > 1:
hostname = sys.argv[1]
print(hostname, zeroconf.cache.entries_with_name(hostname))
cache = zeroconf.cache.cache
zeroconf.close()
# list all known hosts in .local
for key in cache.keys():
if isinstance(cache[key][0], DNSAddress):
print(key, cache[key])
sleep(1)
44 changes: 44 additions & 0 deletions test_zeroconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import zeroconf as r
from zeroconf import (
DNSAddress,
DNSText,
Listener,
ServiceBrowser,
Expand Down Expand Up @@ -204,3 +205,46 @@ def test_dnstext_repr_works():
# from working when the text was longer than 10 bytes
text = DNSText('irrelevant', None, 0, 0, b'12345678901')
repr(text)


def test_dnsaddress_repr_works():
# ipv6 addresses not treated properly
dnsaddr = DNSAddress('aaaa', r._TYPE_A, r._CLASS_IN, 60, '127.0.0.1')
repr(dnsaddr)


def test_unicast_query():
# test for queries fron a random source port
generated = r.DNSOutgoing(r._FLAGS_QR_QUERY)
generated.add_question(r.DNSQuestion("testname.local.", r._TYPE_A,
r._CLASS_IN))
zc = r.Zeroconf()
zc.handle_query(generated, '127.0.0.1', 1782)
zc.handle_query(generated, '127.0.0.1', 53)


def test_handle_read_nonspecialport():
error = socket.error(socket.EBADF)
error.errno = socket.EBADF

zeroconf = Mock()
# packet data captured by running python examples/registration.py --debug
zeroconf.socket.recvfrom = lambda x: (
b'0\x1a\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x08testname\x05local\x00\x00\x01\x00\x01',
('127.0.0.1', 1234))

listener = Listener(zeroconf)
listener.handle_read(zeroconf.socket)


def test_handle_read_dnsport():
error = socket.error(socket.EBADF)
error.errno = socket.EBADF

zeroconf = Mock()
zeroconf.socket.recvfrom = lambda x: (
b'0\x1a\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x08testname\x05local\x00\x00\x01\x00\x01',
('127.0.0.1', 1234))

listener = Listener(zeroconf)
listener.handle_read(zeroconf.socket)
22 changes: 16 additions & 6 deletions zeroconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,9 @@ def __eq__(self, other):

def __repr__(self):
"""String representation"""
try:
return socket.inet_ntoa(self.address)
try: # handle ipv6 addresses
return socket.inet_ntop(socket.AF_INET6 if self.type == _TYPE_AAAA else socket.AF_INET,
self.address)
except Exception as e: # TODO stop catching all Exceptions
log.exception('Unknown error, possibly benign: %r', e)
return self.address
Expand Down Expand Up @@ -510,7 +511,10 @@ def read_others(self):
n = self.num_answers + self.num_authorities + self.num_additionals
for i in xrange(n):
domain = self.read_name()
type, class_, ttl, length = self.unpack(b'!HHiH')
try: # ignore malformed packet
type, class_, ttl, length = self.unpack(b'!HHiH')
except struct.error:
return

rec = None
if type == _TYPE_A:
Expand Down Expand Up @@ -557,8 +561,11 @@ def read_name(self):
first = off

while True:
length = indexbytes(self.data, off)
off += 1
try: # ignore malformed packet
length = indexbytes(self.data, off)
off += 1
except IndexError:
length = 0
if length == 0:
break
t = length & 0xC0
Expand Down Expand Up @@ -897,6 +904,9 @@ def handle_read(self, socket_):
elif port == _DNS_PORT:
self.zc.handle_query(msg, addr, port)
self.zc.handle_query(msg, _MDNS_ADDR, _MDNS_PORT)
# handle unicast queries as per RFC6762 section 6.7
else:
self.zc.handle_query(msg, addr, port)
else:
self.zc.handle_response(msg)

Expand Down Expand Up @@ -1093,7 +1103,7 @@ def __init__(self, type, name, address=None, port=None, weight=0,
self.weight = weight
self.priority = priority
if server:
self.server = server
self.server = server.lower()
else:
self.server = name
self._set_properties(properties)
Expand Down