Example #1
0
    def test_dns_text_repr(self):
        # There was an issue on Python 3 that prevented DNSText's repr
        # from working when the text was longer than 10 bytes
        text = DNSText("irrelevant", None, 0, 0, b"12345678901")
        repr(text)

        text = DNSText("irrelevant", None, 0, 0, b"123")
        repr(text)
Example #2
0
def test_tc_bit_not_set_in_answer_packet():
    """Verify the TC bit is not set when there are no questions and answers exceed the packet size."""
    out = r.DNSOutgoing(const._FLAGS_QR_RESPONSE | const._FLAGS_AA)
    for i in range(30):
        out.add_answer_at_time(
            DNSText(
                ("HASS Bridge W9DN %s._hap._tcp.local." % i),
                const._TYPE_TXT,
                const._CLASS_IN | const._CLASS_UNIQUE,
                const._DNS_OTHER_TTL,
                b'\x13md=HASS Bridge W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1'
                b'\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==',
            ),
            0,
        )

    packets = out.packets()
    assert len(packets) == 3

    first_packet = r.DNSIncoming(packets[0])
    assert first_packet.flags & const._FLAGS_TC == 0
    assert first_packet.valid is True

    second_packet = r.DNSIncoming(packets[1])
    assert second_packet.flags & const._FLAGS_TC == 0
    assert second_packet.valid is True

    third_packet = r.DNSIncoming(packets[2])
    assert third_packet.flags & const._FLAGS_TC == 0
    assert third_packet.valid is True
Example #3
0
def register_service(zc, info, ttl=60, send_num=3):
    """
    like zeroconf.Zeroconf.register_service() but
    just broadcasts send_num packets and then returns
    """
    logger.info("Registering service: {s}".format(s=info))
    now = current_time_millis()
    next_time = now
    i = 0
    while i < 3:
        if now < next_time:
            sleep_time = next_time - now
            logger.debug("sleeping {s}".format(s=sleep_time))
            zc.wait(sleep_time)
            now = current_time_millis()
            continue
        out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
        out.add_answer_at_time(
            DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, ttl, info.name), 0)
        out.add_answer_at_time(
            DNSService(info.name, _TYPE_SRV, _CLASS_IN, ttl, info.priority,
                       info.weight, info.port, info.server), 0)
        out.add_answer_at_time(
            DNSText(info.name, _TYPE_TXT, _CLASS_IN, ttl, info.text), 0)
        if info.address:
            out.add_answer_at_time(
                DNSAddress(info.server, _TYPE_A, _CLASS_IN, ttl, info.address),
                0)
        zc.send(out)
        i += 1
        next_time += _REGISTER_TIME
    logger.debug("done registering service")
Example #4
0
def test_tc_bit_in_query_packet():
    """Verify the TC bit is set when known answers exceed the packet size."""
    out = r.DNSOutgoing(const._FLAGS_QR_QUERY | const._FLAGS_AA)
    type_ = "_hap._tcp.local."
    out.add_question(r.DNSQuestion(type_, const._TYPE_PTR, const._CLASS_IN))

    for i in range(30):
        out.add_answer_at_time(
            DNSText(
                ("HASS Bridge W9DN %s._hap._tcp.local." % i),
                const._TYPE_TXT,
                const._CLASS_IN | const._CLASS_UNIQUE,
                const._DNS_OTHER_TTL,
                b'\x13md=HASS Bridge W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1'
                b'\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==',
            ),
            0,
        )

    packets = out.packets()
    assert len(packets) == 3

    first_packet = r.DNSIncoming(packets[0])
    assert first_packet.truncated
    assert first_packet.valid is True

    second_packet = r.DNSIncoming(packets[1])
    assert second_packet.truncated
    assert second_packet.valid is True

    third_packet = r.DNSIncoming(packets[2])
    assert not third_packet.truncated
    assert third_packet.valid is True
Example #5
0
def test_records_same_packet_share_fate():
    """Test records in the same packet all have the same created time."""
    out = r.DNSOutgoing(const._FLAGS_QR_QUERY | const._FLAGS_AA)
    type_ = "_hap._tcp.local."
    out.add_question(r.DNSQuestion(type_, const._TYPE_PTR, const._CLASS_IN))

    for i in range(30):
        out.add_answer_at_time(
            DNSText(
                ("HASS Bridge W9DN %s._hap._tcp.local." % i),
                const._TYPE_TXT,
                const._CLASS_IN | const._CLASS_UNIQUE,
                const._DNS_OTHER_TTL,
                b'\x13md=HASS Bridge W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1'
                b'\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==',
            ),
            0,
        )

    for packet in out.packets():
        dnsin = DNSIncoming(packet)
        first_time = dnsin.answers[0].created
        for answer in dnsin.answers:
            assert answer.created == first_time
Example #6
0
def test_dnstext_repr_works():
    # There was an issue on Python 3 that prevented DNSText's repr
    # from working when the text was longer than 10 bytes
    text = DNSText('irrelevant', None, 0, 0, b'12345678901')
    repr(text)
Example #7
0
    "70-35-60-63.1 Ohana._sleep-proxy._udp.local.",
)
SLEEP_PROXY_SRV_RECORD = DNSService(
    "70-35-60-63.1 Ohana._sleep-proxy._udp.local.",
    const._TYPE_SRV,
    const._CLASS_IN,
    const._DNS_HOST_TTL,
    0,
    0,
    54942,
    "Ohana.local.",
)
SLEEP_PROXY_TXT_RECORD = DNSText(
    "70-35-60-63.1 Ohana._sleep-proxy._udp.local.",
    const._TYPE_TXT,
    const._CLASS_IN,
    const._DNS_OTHER_TTL,
    b"",
)
AIRPLAY_PTR_RECORD = DNSPointer(
    "_airplay._tcp.local.",
    const._TYPE_PTR,
    const._CLASS_IN,
    const._DNS_OTHER_TTL,
    "Ohana._airplay._tcp.local.",
)
AIRPLAY_SRV_RECORD = DNSService(
    "Ohana._airplay._tcp.local.",
    const._TYPE_SRV,
    const._CLASS_IN,
    const._DNS_HOST_TTL,
Example #8
0
def test_dns_compression_rollback_for_corruption():
    """Verify rolling back does not lead to dns compression corruption."""
    out = r.DNSOutgoing(const._FLAGS_QR_RESPONSE | const._FLAGS_AA)
    address = socket.inet_pton(socket.AF_INET, "192.168.208.5")

    additionals = [
        {
            "name":
            "HASS Bridge ZJWH FF5137._hap._tcp.local.",
            "address":
            address,
            "port":
            51832,
            "text":
            b"\x13md=HASS Bridge"
            b" ZJWH\x06pv=1.0\x14id=01:6B:30:FF:51:37\x05c#=12\x04s#=1\x04ff=0\x04"
            b"ci=2\x04sf=0\x0bsh=L0m/aQ==",
        },
        {
            "name":
            "HASS Bridge 3K9A C2582A._hap._tcp.local.",
            "address":
            address,
            "port":
            51834,
            "text":
            b"\x13md=HASS Bridge"
            b" 3K9A\x06pv=1.0\x14id=E2:AA:5B:C2:58:2A\x05c#=12\x04s#=1\x04ff=0\x04"
            b"ci=2\x04sf=0\x0bsh=b2CnzQ==",
        },
        {
            "name":
            "Master Bed TV CEDB27._hap._tcp.local.",
            "address":
            address,
            "port":
            51830,
            "text":
            b"\x10md=Master Bed"
            b" TV\x06pv=1.0\x14id=9E:B7:44:CE:DB:27\x05c#=18\x04s#=1\x04ff=0\x05"
            b"ci=31\x04sf=0\x0bsh=CVj1kw==",
        },
        {
            "name":
            "Living Room TV 921B77._hap._tcp.local.",
            "address":
            address,
            "port":
            51833,
            "text":
            b"\x11md=Living Room"
            b" TV\x06pv=1.0\x14id=11:61:E7:92:1B:77\x05c#=17\x04s#=1\x04ff=0\x05"
            b"ci=31\x04sf=0\x0bsh=qU77SQ==",
        },
        {
            "name":
            "HASS Bridge ZC8X FF413D._hap._tcp.local.",
            "address":
            address,
            "port":
            51829,
            "text":
            b"\x13md=HASS Bridge"
            b" ZC8X\x06pv=1.0\x14id=96:14:45:FF:41:3D\x05c#=12\x04s#=1\x04ff=0\x04"
            b"ci=2\x04sf=0\x0bsh=b0QZlg==",
        },
        {
            "name":
            "HASS Bridge WLTF 4BE61F._hap._tcp.local.",
            "address":
            address,
            "port":
            51837,
            "text":
            b"\x13md=HASS Bridge"
            b" WLTF\x06pv=1.0\x14id=E0:E7:98:4B:E6:1F\x04c#=2\x04s#=1\x04ff=0\x04"
            b"ci=2\x04sf=0\x0bsh=ahAISA==",
        },
        {
            "name":
            "FrontdoorCamera 8941D1._hap._tcp.local.",
            "address":
            address,
            "port":
            54898,
            "text":
            b"\x12md=FrontdoorCamera\x06pv=1.0\x14id=9F:B7:DC:89:41:D1\x04c#=2\x04"
            b"s#=1\x04ff=0\x04ci=2\x04sf=0\x0bsh=0+MXmA==",
        },
        {
            "name":
            "HASS Bridge W9DN 5B5CC5._hap._tcp.local.",
            "address":
            address,
            "port":
            51836,
            "text":
            b"\x13md=HASS Bridge"
            b" W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1\x04ff=0\x04"
            b"ci=2\x04sf=0\x0bsh=6fLM5A==",
        },
        {
            "name":
            "HASS Bridge Y9OO EFF0A7._hap._tcp.local.",
            "address":
            address,
            "port":
            51838,
            "text":
            b"\x13md=HASS Bridge"
            b" Y9OO\x06pv=1.0\x14id=D3:FE:98:EF:F0:A7\x04c#=2\x04s#=1\x04ff=0\x04"
            b"ci=2\x04sf=0\x0bsh=u3bdfw==",
        },
        {
            "name":
            "Snooze Room TV 6B89B0._hap._tcp.local.",
            "address":
            address,
            "port":
            51835,
            "text":
            b"\x11md=Snooze Room"
            b" TV\x06pv=1.0\x14id=5F:D5:70:6B:89:B0\x05c#=17\x04s#=1\x04ff=0\x05"
            b"ci=31\x04sf=0\x0bsh=xNTqsg==",
        },
        {
            "name":
            "AlexanderHomeAssistant 74651D._hap._tcp.local.",
            "address":
            address,
            "port":
            54811,
            "text":
            b"\x19md=AlexanderHomeAssistant\x06pv=1.0\x14id=59:8A:0B:74:65:1D\x05"
            b"c#=14\x04s#=1\x04ff=0\x04ci=2\x04sf=0\x0bsh=ccZLPA==",
        },
        {
            "name":
            "HASS Bridge OS95 39C053._hap._tcp.local.",
            "address":
            address,
            "port":
            51831,
            "text":
            b"\x13md=HASS Bridge"
            b" OS95\x06pv=1.0\x14id=7E:8C:E6:39:C0:53\x05c#=12\x04s#=1\x04ff=0\x04ci=2"
            b"\x04sf=0\x0bsh=Xfe5LQ==",
        },
    ]

    out.add_answer_at_time(
        DNSText(
            "HASS Bridge W9DN 5B5CC5._hap._tcp.local.",
            const._TYPE_TXT,
            const._CLASS_IN | const._CLASS_UNIQUE,
            const._DNS_OTHER_TTL,
            b'\x13md=HASS Bridge W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1'
            b'\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==',
        ),
        0,
    )

    for record in additionals:
        out.add_additional_answer(
            r.DNSService(
                record["name"],  # type: ignore
                const._TYPE_SRV,
                const._CLASS_IN | const._CLASS_UNIQUE,
                const._DNS_HOST_TTL,
                0,
                0,
                record["port"],  # type: ignore
                record["name"],  # type: ignore
            ))
        out.add_additional_answer(
            r.DNSText(
                record["name"],  # type: ignore
                const._TYPE_TXT,
                const._CLASS_IN | const._CLASS_UNIQUE,
                const._DNS_OTHER_TTL,
                record["text"],  # type: ignore
            ))
        out.add_additional_answer(
            r.DNSAddress(
                record["name"],  # type: ignore
                const._TYPE_A,
                const._CLASS_IN | const._CLASS_UNIQUE,
                const._DNS_HOST_TTL,
                record["address"],  # type: ignore
            ))

    for packet in out.packets():
        # Verify we can process the packets we created to
        # ensure there is no corruption with the dns compression
        incoming = r.DNSIncoming(packet)
        assert incoming.valid is True