feat: speed up parsing NSEC records (#1169) · python-zeroconf/python-zeroconf@06fa94d

3 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -3,7 +3,15 @@

33

import timeit

44

from typing import List

55
6-

from zeroconf import DNSAddress, DNSIncoming, DNSOutgoing, DNSService, DNSText, const

6+

from zeroconf import (

7+

DNSAddress,

8+

DNSIncoming,

9+

DNSNsec,

10+

DNSOutgoing,

11+

DNSService,

12+

DNSText,

13+

const,

14+

)

715
816
917

def generate_packets() -> List[bytes]:

@@ -150,6 +158,16 @@ def generate_packets() -> List[bytes]:

150158

record["address"], # type: ignore

151159

)

152160

)

161+

out.add_additional_answer(

162+

DNSNsec(

163+

record["name"], # type: ignore

164+

const._TYPE_NSEC,

165+

const._CLASS_IN | const._CLASS_UNIQUE,

166+

const._DNS_OTHER_TTL,

167+

record["name"], # type: ignore

168+

[const._TYPE_TXT, const._TYPE_SRV],

169+

)

170+

)

153171
154172

return out.packets()

155173
Original file line numberDiff line numberDiff line change

@@ -95,6 +95,16 @@ cdef class DNSIncoming:

9595

)

9696

cdef _read_record(self, object domain, unsigned int type_, object class_, object ttl, unsigned int length)

9797
98+

@cython.locals(

99+

offset=cython.uint,

100+

offset_plus_one=cython.uint,

101+

offset_plus_two=cython.uint,

102+

window=cython.uint,

103+

bit=cython.uint,

104+

byte=cython.uint,

105+

i=cython.uint,

106+

bitmap_length=cython.uint,

107+

)

98108

cdef _read_bitmap(self, unsigned int end)

99109
100110

cdef _read_name(self)

Original file line numberDiff line numberDiff line change

@@ -318,9 +318,13 @@ def _read_bitmap(self, end: int) -> List[int]:

318318

"""Reads an NSEC bitmap from the packet."""

319319

rdtypes = []

320320

while self.offset < end:

321-

window = self.data[self.offset]

322-

bitmap_length = self.data[self.offset + 1]

323-

for i, byte in enumerate(self.data[self.offset + 2 : self.offset + 2 + bitmap_length]):

321+

offset = self.offset

322+

offset_plus_one = offset + 1

323+

offset_plus_two = offset + 2

324+

window = self.data[offset]

325+

bitmap_length = self.data[offset_plus_one]

326+

bitmap_end = offset_plus_two + bitmap_length

327+

for i, byte in enumerate(self.data[offset_plus_two:bitmap_end]):

324328

for bit in range(0, 8):

325329

if byte & (0x80 >> bit):

326330

rdtypes.append(bit + window * 256 + i * 8)