]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_TCPKeepAlive.py
5 from dnsdisttests
import DNSDistTest
12 class TestTCPKeepAlive(DNSDistTest
):
14 These tests make sure that dnsdist keeps the TCP connection alive
15 in various cases, like cache hits, self-generated answer, and
16 that it doesn't in error cases (Drop, invalid queries...)
20 _maxTCPQueriesPerConn
= 99
21 _maxTCPConnsPerClient
= 100
22 _maxTCPConnDuration
= 99
23 _config_template
= """
24 newServer{address="127.0.0.1:%s"}
26 setMaxTCPQueriesPerConnection(%s)
27 setMaxTCPConnectionsPerClient(%s)
28 setMaxTCPConnectionDuration(%s)
29 pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
30 getPool(""):setCache(pc)
31 addAction("largernumberofconnections.tcpka.tests.powerdns.com.", SetSkipCacheAction())
32 addAction("refused.tcpka.tests.powerdns.com.", RCodeAction(DNSRCode.REFUSED))
33 addAction("dropped.tcpka.tests.powerdns.com.", DropAction())
34 addResponseAction("dropped-response.tcpka.tests.powerdns.com.", DropResponseAction())
35 -- create the pool named "nosuchpool"
37 addAction("nodownstream-servfail.tcpka.tests.powerdns.com.", PoolAction("nosuchpool"))
38 setServFailWhenNoServer(true)
40 _config_params
= ['_testServerPort', '_tcpIdleTimeout', '_maxTCPQueriesPerConn', '_maxTCPConnsPerClient', '_maxTCPConnDuration']
42 def testTCPKaSelfGenerated(self
):
44 TCP KeepAlive: Self-generated answer
46 name
= 'refused.tcpka.tests.powerdns.com.'
47 query
= dns
.message
.make_query(name
, 'A', 'IN')
48 query
.flags
&= ~dns
.flags
.RD
49 expectedResponse
= dns
.message
.make_response(query
)
50 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
52 conn
= self
.openTCPConnection()
57 self
.sendTCPQueryOverConnection(conn
, query
)
58 response
= self
.recvTCPResponseOverConnection(conn
)
61 self
.assertEqual(expectedResponse
, response
)
67 self
.assertEqual(count
, 5)
69 def testTCPKaCacheHit(self
):
71 TCP KeepAlive: Cache Hit
73 name
= 'cachehit.tcpka.tests.powerdns.com.'
74 query
= dns
.message
.make_query(name
, 'A', 'IN')
75 expectedResponse
= dns
.message
.make_response(query
)
76 rrset
= dns
.rrset
.from_text(name
,
81 expectedResponse
.answer
.append(rrset
)
83 # first query to fill the cache
84 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, expectedResponse
)
85 self
.assertTrue(receivedQuery
)
86 self
.assertTrue(receivedResponse
)
87 receivedQuery
.id = query
.id
88 self
.assertEqual(query
, receivedQuery
)
89 self
.assertEqual(receivedResponse
, expectedResponse
)
91 conn
= self
.openTCPConnection()
96 self
.sendTCPQueryOverConnection(conn
, query
)
97 response
= self
.recvTCPResponseOverConnection(conn
)
100 self
.assertEqual(expectedResponse
, response
)
106 self
.assertEqual(count
, 5)
108 def testTCPKaNoDownstreamServFail(self
):
110 TCP KeepAlive: No downstream ServFail
112 The query is routed to a pool that has no server,
113 and dnsdist is configured to send a ServFail when
114 that happens. We should keep the TCP connection open.
116 name
= 'nodownstream-servfail.tcpka.tests.powerdns.com.'
117 query
= dns
.message
.make_query(name
, 'A', 'IN')
118 expectedResponse
= dns
.message
.make_response(query
)
119 expectedResponse
.set_rcode(dns
.rcode
.SERVFAIL
)
121 conn
= self
.openTCPConnection()
126 self
.sendTCPQueryOverConnection(conn
, query
)
127 response
= self
.recvTCPResponseOverConnection(conn
)
130 self
.assertEqual(expectedResponse
, response
)
136 self
.assertEqual(count
, 5)
138 def testTCPKaQRBitSet(self
):
140 TCP KeepAlive: QR bit set in question
142 name
= 'qrset.tcpka.tests.powerdns.com.'
143 query
= dns
.message
.make_query(name
, 'A', 'IN')
144 query
.flags |
= dns
.flags
.QR
146 conn
= self
.openTCPConnection()
151 self
.sendTCPQueryOverConnection(conn
, query
)
152 response
= self
.recvTCPResponseOverConnection(conn
)
160 self
.assertEqual(count
, 0)
162 def testTCPKaDrop(self
):
166 name
= 'dropped.tcpka.tests.powerdns.com.'
167 query
= dns
.message
.make_query(name
, 'A', 'IN')
168 query
.flags |
= dns
.flags
.QR
170 conn
= self
.openTCPConnection()
175 self
.sendTCPQueryOverConnection(conn
, query
)
176 response
= self
.recvTCPResponseOverConnection(conn
)
184 self
.assertEqual(count
, 0)
186 def testTCPKaDropResponse(self
):
188 TCP KeepAlive: Drop Response
190 name
= 'dropped-response.tcpka.tests.powerdns.com.'
191 query
= dns
.message
.make_query(name
, 'A', 'IN')
193 conn
= self
.openTCPConnection()
198 self
.sendTCPQueryOverConnection(conn
, query
)
199 response
= self
.recvTCPResponseOverConnection(conn
)
207 self
.assertEqual(count
, 0)
209 def testTCPKaLargeNumberOfConnections(self
):
211 TCP KeepAlive: Large number of connections
213 name
= 'largernumberofconnections.tcpka.tests.powerdns.com.'
214 query
= dns
.message
.make_query(name
, 'A', 'IN')
215 expectedResponse
= dns
.message
.make_response(query
)
216 #expectedResponse.set_rcode(dns.rcode.SERVFAIL)
217 rrset
= dns
.rrset
.from_text(name
,
222 expectedResponse
.answer
.append(rrset
)
224 # number of connections
226 # number of queries per connections
227 numQueriesPerConn
= 4
231 for idx
in range(numConns
):
232 conns
.append(self
.openTCPConnection())
235 for idx
in range(numConns
* numQueriesPerConn
):
237 conn
= conns
[idx
% numConns
]
238 self
.sendTCPQueryOverConnection(conn
, query
, response
=expectedResponse
)
239 response
= self
.recvTCPResponseOverConnection(conn
)
242 self
.assertEqual(expectedResponse
, response
)
250 self
.assertEqual(count
, numConns
* numQueriesPerConn
)
252 class TestTCPKeepAliveNoDownstreamDrop(DNSDistTest
):
254 This test makes sure that dnsdist drops the TCP connection
255 if no downstream server is available and setServFailWhenNoServer()
260 _maxTCPQueriesPerConn
= 99
261 _maxTCPConnsPerClient
= 3
262 _maxTCPConnDuration
= 99
263 _config_template
= """
264 newServer{address="127.0.0.1:%s"}
265 setTCPRecvTimeout(%s)
266 setMaxTCPQueriesPerConnection(%s)
267 setMaxTCPConnectionsPerClient(%s)
268 setMaxTCPConnectionDuration(%s)
269 -- create the pool named "nosuchpool"
270 getPool("nosuchpool")
271 addAction("nodownstream-drop.tcpka.tests.powerdns.com.", PoolAction("nosuchpool"))
273 _config_params
= ['_testServerPort', '_tcpIdleTimeout', '_maxTCPQueriesPerConn', '_maxTCPConnsPerClient', '_maxTCPConnDuration']
275 def testTCPKaNoDownstreamDrop(self
):
277 TCP KeepAlive: No downstream Drop
279 The query is routed to a pool that has no server,
280 and dnsdist is configured to drop the query when
281 that happens. We should close the TCP connection right away.
283 name
= 'nodownstream-drop.tcpka.tests.powerdns.com.'
284 query
= dns
.message
.make_query(name
, 'A', 'IN')
286 conn
= self
.openTCPConnection()
291 self
.sendTCPQueryOverConnection(conn
, query
)
292 response
= self
.recvTCPResponseOverConnection(conn
)
300 self
.assertEqual(count
, 0)