| 62 | |
| 63 | @dataclass |
| 64 | class ResourceRecord(serializable.SerializableDataclass): |
| 65 | DEFAULT_TTL: ClassVar[int] = 60 |
| 66 | HEADER: ClassVar[struct.Struct] = struct.Struct("!HHIH") |
| 67 | |
| 68 | name: str |
| 69 | type: int |
| 70 | class_: int |
| 71 | ttl: int |
| 72 | data: bytes |
| 73 | |
| 74 | def __str__(self) -> str: |
| 75 | return str(self._data_json()) |
| 76 | |
| 77 | @property |
| 78 | def text(self) -> str: |
| 79 | return self.data.decode("utf-8") |
| 80 | |
| 81 | @text.setter |
| 82 | def text(self, value: str) -> None: |
| 83 | self.data = value.encode("utf-8") |
| 84 | |
| 85 | @property |
| 86 | def ipv4_address(self) -> IPv4Address: |
| 87 | return IPv4Address(self.data) |
| 88 | |
| 89 | @ipv4_address.setter |
| 90 | def ipv4_address(self, ip: IPv4Address) -> None: |
| 91 | self.data = ip.packed |
| 92 | |
| 93 | @property |
| 94 | def ipv6_address(self) -> IPv6Address: |
| 95 | return IPv6Address(self.data) |
| 96 | |
| 97 | @ipv6_address.setter |
| 98 | def ipv6_address(self, ip: IPv6Address) -> None: |
| 99 | self.data = ip.packed |
| 100 | |
| 101 | @property |
| 102 | def domain_name(self) -> str: |
| 103 | return domain_names.unpack(self.data) |
| 104 | |
| 105 | @domain_name.setter |
| 106 | def domain_name(self, name: str) -> None: |
| 107 | self.data = domain_names.pack(name) |
| 108 | |
| 109 | @property |
| 110 | def https_alpn(self) -> tuple[bytes, ...] | None: |
| 111 | record = https_records.unpack(self.data) |
| 112 | alpn_bytes = record.params.get(SVCParamKeys.ALPN.value, None) |
| 113 | if alpn_bytes is not None: |
| 114 | i = 0 |
| 115 | ret = [] |
| 116 | while i < len(alpn_bytes): |
| 117 | token_len = alpn_bytes[i] |
| 118 | ret.append(alpn_bytes[i + 1 : i + 1 + token_len]) |
| 119 | i += token_len + 1 |
| 120 | return tuple(ret) |
| 121 | else: |
no outgoing calls
no test coverage detected
searching dependent graphs…