or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dns-constants.mddns-exceptions.mddns-messages.mddns-names.mddns-queries.mddns-records.mddns-resolution.mddns-updates.mddns-utilities.mddns-zones.mddnssec.mdindex.mdtsig.md

dns-queries.mddocs/

0

# DNS Queries

1

2

Low-level DNS query functions that provide direct control over DNS message exchange with nameservers. These functions handle UDP and TCP communication, zone transfers, and provide fine-grained control over query parameters.

3

4

## Capabilities

5

6

### UDP Queries

7

8

Send DNS queries using UDP protocol with full control over query parameters and response handling.

9

10

```python { .api }

11

def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,

12

ignore_unexpected=False, one_rr_per_rrset=False, ignore_trailing=False):

13

"""

14

Send a DNS query via UDP.

15

16

Args:

17

q (dns.message.Message): DNS query message

18

where (str): Nameserver IP address

19

timeout (float): Query timeout in seconds

20

port (int): Destination port (default 53)

21

af (int): Address family (socket.AF_INET or socket.AF_INET6)

22

source (str): Source IP address

23

source_port (int): Source port number

24

ignore_unexpected (bool): Ignore responses from unexpected sources

25

one_rr_per_rrset (bool): Put each RR in its own RRset

26

ignore_trailing (bool): Ignore trailing junk in packets

27

28

Returns:

29

dns.message.Message: DNS response message

30

"""

31

32

def send_udp(sock, what, destination, expiration=None):

33

"""

34

Send a DNS message to the specified UDP socket destination.

35

36

Args:

37

sock (socket): UDP socket

38

what (dns.message.Message or bytes): Message to send

39

destination (tuple): (address, port) tuple

40

expiration (float): Absolute expiration time

41

"""

42

43

def receive_udp(sock, destination, expiration=None, ignore_unexpected=False,

44

one_rr_per_rrset=False, keyring=None, request_mac=b'',

45

ignore_trailing=False):

46

"""

47

Read a DNS message from a UDP socket.

48

49

Args:

50

sock (socket): UDP socket

51

destination (tuple): Expected source (address, port)

52

expiration (float): Absolute expiration time

53

ignore_unexpected (bool): Ignore responses from unexpected sources

54

one_rr_per_rrset (bool): Put each RR in its own RRset

55

keyring (dict): TSIG keyring for validation

56

request_mac (bytes): TSIG MAC from request

57

ignore_trailing (bool): Ignore trailing junk in packets

58

59

Returns:

60

dns.message.Message: DNS response message

61

"""

62

```

63

64

### TCP Queries

65

66

Send DNS queries using TCP protocol for reliable delivery and large responses.

67

68

```python { .api }

69

def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,

70

one_rr_per_rrset=False, ignore_trailing=False):

71

"""

72

Send a DNS query via TCP.

73

74

Args:

75

q (dns.message.Message): DNS query message

76

where (str): Nameserver IP address

77

timeout (float): Query timeout in seconds

78

port (int): Destination port (default 53)

79

af (int): Address family (socket.AF_INET or socket.AF_INET6)

80

source (str): Source IP address

81

source_port (int): Source port number

82

one_rr_per_rrset (bool): Put each RR in its own RRset

83

ignore_trailing (bool): Ignore trailing junk in packets

84

85

Returns:

86

dns.message.Message: DNS response message

87

"""

88

89

def send_tcp(sock, what, expiration=None):

90

"""

91

Send a DNS message to the specified TCP socket.

92

93

Args:

94

sock (socket): TCP socket

95

what (dns.message.Message or bytes): Message to send

96

expiration (float): Absolute expiration time

97

"""

98

99

def receive_tcp(sock, expiration=None, one_rr_per_rrset=False, keyring=None,

100

request_mac=b'', ignore_trailing=False):

101

"""

102

Read a DNS message from a TCP socket.

103

104

Args:

105

sock (socket): TCP socket

106

expiration (float): Absolute expiration time

107

one_rr_per_rrset (bool): Put each RR in its own RRset

108

keyring (dict): TSIG keyring for validation

109

request_mac (bytes): TSIG MAC from request

110

ignore_trailing (bool): Ignore trailing junk in packets

111

112

Returns:

113

dns.message.Message: DNS response message

114

"""

115

```

116

117

### Zone Transfers

118

119

Perform zone transfers (AXFR/IXFR) to retrieve complete zone data from authoritative servers.

120

121

```python { .api }

122

def xfr(where, zone, rdtype='AXFR', rdclass='IN', timeout=None, port=53,

123

keyring=None, keyname=None, relativize=True, af=None, lifetime=None,

124

source=None, source_port=0, serial=0, use_udp=False,

125

keyalgorithm='HMAC-MD5.SIG-ALG.REG.INT'):

126

"""

127

Perform a zone transfer and return a generator yielding messages.

128

129

Args:

130

where (str): Nameserver IP address

131

zone (str or dns.name.Name): Zone name

132

rdtype (str or int): Transfer type ('AXFR' or 'IXFR')

133

rdclass (str or int): Record class (default 'IN')

134

timeout (float): Query timeout in seconds

135

port (int): Destination port (default 53)

136

keyring (dict): TSIG keyring for authentication

137

keyname (str or dns.name.Name): TSIG key name

138

relativize (bool): Relativize names to zone origin

139

af (int): Address family

140

lifetime (float): Total transfer lifetime

141

source (str): Source IP address

142

source_port (int): Source port number

143

serial (int): Serial number for IXFR

144

use_udp (bool): Use UDP for IXFR

145

keyalgorithm (str): TSIG algorithm name

146

147

Yields:

148

dns.message.Message: Transfer response messages

149

"""

150

```

151

152

### Helper Functions

153

154

Utility functions for working with sockets and query timing.

155

156

```python { .api }

157

def _compute_expiration(timeout):

158

"""

159

Compute absolute expiration time from timeout.

160

161

Args:

162

timeout (float): Timeout in seconds

163

164

Returns:

165

float: Absolute expiration time

166

"""

167

168

def _matches_destination(af, address, destination, ignore_unexpected):

169

"""

170

Check if address matches expected destination.

171

172

Args:

173

af (int): Address family

174

address (tuple): Actual source address

175

destination (tuple): Expected destination

176

ignore_unexpected (bool): Ignore unexpected sources

177

178

Returns:

179

bool: True if addresses match or should be ignored

180

"""

181

```

182

183

## Usage Examples

184

185

### Basic UDP Query

186

187

```python

188

import dns.message

189

import dns.query

190

import dns.name

191

import dns.rdatatype

192

193

# Create a query message

194

qname = dns.name.from_text('example.com')

195

q = dns.message.make_query(qname, dns.rdatatype.A)

196

197

# Send UDP query

198

response = dns.query.udp(q, '8.8.8.8', timeout=10)

199

200

# Process response

201

for rrset in response.answer:

202

for rdata in rrset:

203

if rrset.rdtype == dns.rdatatype.A:

204

print(f"IP address: {rdata.address}")

205

```

206

207

### TCP Query with Custom Options

208

209

```python

210

import dns.message

211

import dns.query

212

import dns.name

213

import dns.rdatatype

214

215

# Create query with EDNS

216

qname = dns.name.from_text('large-response.example.com')

217

q = dns.message.make_query(qname, dns.rdatatype.TXT, use_edns=0, payload=4096)

218

219

# Send TCP query with custom source

220

response = dns.query.tcp(q, '8.8.8.8', timeout=30, source='192.168.1.100',

221

source_port=12345)

222

223

# Check response

224

print(f"Response code: {response.rcode()}")

225

print(f"Answer count: {len(response.answer)}")

226

```

227

228

### Zone Transfer

229

230

```python

231

import dns.query

232

import dns.zone

233

import dns.name

234

235

# Perform AXFR zone transfer

236

zone_name = dns.name.from_text('example.com')

237

zone_messages = dns.query.xfr('ns1.example.com', zone_name,

238

timeout=300, lifetime=600)

239

240

# Build zone from transfer

241

zone = dns.zone.from_xfr(zone_messages)

242

243

# Iterate through zone records

244

for name, node in zone.nodes.items():

245

for rdataset in node.rdatasets:

246

print(f"{name} {rdataset.ttl} {rdataset.rdclass} {rdataset.rdtype}")

247

for rdata in rdataset:

248

print(f" {rdata}")

249

```

250

251

### Authenticated Query with TSIG

252

253

```python

254

import dns.message

255

import dns.query

256

import dns.tsigkeyring

257

import dns.name

258

259

# Create TSIG keyring

260

keyring = dns.tsigkeyring.from_text({

261

'key-name': 'base64-encoded-key'

262

})

263

264

# Create authenticated query

265

qname = dns.name.from_text('secure.example.com')

266

q = dns.message.make_query(qname, dns.rdatatype.A)

267

q.use_tsig(keyring, 'key-name')

268

269

# Send authenticated query

270

response = dns.query.udp(q, '192.168.1.1', timeout=10)

271

272

# Verify response authentication

273

if response.tsig_error() == 0:

274

print("Response verified successfully")

275

else:

276

print(f"TSIG verification failed: {response.tsig_error()}")

277

```

278

279

## Exceptions

280

281

```python { .api }

282

class UnexpectedSource(DNSException):

283

"""A DNS query response came from an unexpected address or port."""

284

285

class BadResponse(DNSException):

286

"""A DNS query response does not respond to the question asked."""

287

288

class TransferError(DNSException):

289

"""A zone transfer response had a non-zero rcode."""

290

```