]>
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.", SkipCacheAction())
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 expectedResponse
= dns
.message
.make_response(query
)
49 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
51 conn
= self
.openTCPConnection()
56 self
.sendTCPQueryOverConnection(conn
, query
)
57 response
= self
.recvTCPResponseOverConnection(conn
)
60 self
.assertEquals(expectedResponse
, response
)
66 self
.assertEqual(count
, 5)
68 def testTCPKaCacheHit(self
):
70 TCP KeepAlive: Cache Hit
72 name
= 'cachehit.tcpka.tests.powerdns.com.'
73 query
= dns
.message
.make_query(name
, 'A', 'IN')
74 expectedResponse
= dns
.message
.make_response(query
)
75 rrset
= dns
.rrset
.from_text(name
,
80 expectedResponse
.answer
.append(rrset
)
82 # first query to fill the cache
83 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, expectedResponse
)
84 self
.assertTrue(receivedQuery
)
85 self
.assertTrue(receivedResponse
)
86 receivedQuery
.id = query
.id
87 self
.assertEquals(query
, receivedQuery
)
88 self
.assertEquals(receivedResponse
, expectedResponse
)
90 conn
= self
.openTCPConnection()
95 self
.sendTCPQueryOverConnection(conn
, query
)
96 response
= self
.recvTCPResponseOverConnection(conn
)
99 self
.assertEquals(expectedResponse
, response
)
105 self
.assertEqual(count
, 5)
107 def testTCPKaNoDownstreamServFail(self
):
109 TCP KeepAlive: No downstream ServFail
111 The query is routed to a pool that has no server,
112 and dnsdist is configured to send a ServFail when
113 that happens. We should keep the TCP connection open.
115 name
= 'nodownstream-servfail.tcpka.tests.powerdns.com.'
116 query
= dns
.message
.make_query(name
, 'A', 'IN')
117 expectedResponse
= dns
.message
.make_response(query
)
118 expectedResponse
.set_rcode(dns
.rcode
.SERVFAIL
)
120 conn
= self
.openTCPConnection()
125 self
.sendTCPQueryOverConnection(conn
, query
)
126 response
= self
.recvTCPResponseOverConnection(conn
)
129 self
.assertEquals(expectedResponse
, response
)
135 self
.assertEqual(count
, 5)
137 def testTCPKaQRBitSet(self
):
139 TCP KeepAlive: QR bit set in question
141 name
= 'qrset.tcpka.tests.powerdns.com.'
142 query
= dns
.message
.make_query(name
, 'A', 'IN')
143 query
.flags |
= dns
.flags
.QR
145 conn
= self
.openTCPConnection()
150 self
.sendTCPQueryOverConnection(conn
, query
)
151 response
= self
.recvTCPResponseOverConnection(conn
)
159 self
.assertEqual(count
, 0)
161 def testTCPKaDrop(self
):
165 name
= 'dropped.tcpka.tests.powerdns.com.'
166 query
= dns
.message
.make_query(name
, 'A', 'IN')
167 query
.flags |
= dns
.flags
.QR
169 conn
= self
.openTCPConnection()
174 self
.sendTCPQueryOverConnection(conn
, query
)
175 response
= self
.recvTCPResponseOverConnection(conn
)
183 self
.assertEqual(count
, 0)
185 def testTCPKaDropResponse(self
):
187 TCP KeepAlive: Drop Response
189 name
= 'dropped-response.tcpka.tests.powerdns.com.'
190 query
= dns
.message
.make_query(name
, 'A', 'IN')
192 conn
= self
.openTCPConnection()
197 self
.sendTCPQueryOverConnection(conn
, query
)
198 response
= self
.recvTCPResponseOverConnection(conn
)
206 self
.assertEqual(count
, 0)
208 def testTCPKaLargeNumberOfConnections(self
):
210 TCP KeepAlive: Large number of connections
212 name
= 'largernumberofconnections.tcpka.tests.powerdns.com.'
213 query
= dns
.message
.make_query(name
, 'A', 'IN')
214 expectedResponse
= dns
.message
.make_response(query
)
215 #expectedResponse.set_rcode(dns.rcode.SERVFAIL)
216 rrset
= dns
.rrset
.from_text(name
,
221 expectedResponse
.answer
.append(rrset
)
223 # number of connections
225 # number of queries per connections
226 numQueriesPerConn
= 4
230 for idx
in range(numConns
):
231 conns
.append(self
.openTCPConnection())
234 for idx
in range(numConns
* numQueriesPerConn
):
236 conn
= conns
[idx
% numConns
]
237 self
.sendTCPQueryOverConnection(conn
, query
, response
=expectedResponse
)
238 response
= self
.recvTCPResponseOverConnection(conn
)
241 self
.assertEquals(expectedResponse
, response
)
249 self
.assertEqual(count
, numConns
* numQueriesPerConn
)
251 class TestTCPKeepAliveNoDownstreamDrop(DNSDistTest
):
253 This test makes sure that dnsdist drops the TCP connection
254 if no downstream server is available and setServFailWhenNoServer()
259 _maxTCPQueriesPerConn
= 99
260 _maxTCPConnsPerClient
= 3
261 _maxTCPConnDuration
= 99
262 _config_template
= """
263 newServer{address="127.0.0.1:%s"}
264 setTCPRecvTimeout(%s)
265 setMaxTCPQueriesPerConnection(%s)
266 setMaxTCPConnectionsPerClient(%s)
267 setMaxTCPConnectionDuration(%s)
268 -- create the pool named "nosuchpool"
269 getPool("nosuchpool")
270 addAction("nodownstream-drop.tcpka.tests.powerdns.com.", PoolAction("nosuchpool"))
272 _config_params
= ['_testServerPort', '_tcpIdleTimeout', '_maxTCPQueriesPerConn', '_maxTCPConnsPerClient', '_maxTCPConnDuration']
274 def testTCPKaNoDownstreamDrop(self
):
276 TCP KeepAlive: No downstream Drop
278 The query is routed to a pool that has no server,
279 and dnsdist is configured to drop the query when
280 that happens. We should close the TCP connection right away.
282 name
= 'nodownstream-drop.tcpka.tests.powerdns.com.'
283 query
= dns
.message
.make_query(name
, 'A', 'IN')
285 conn
= self
.openTCPConnection()
290 self
.sendTCPQueryOverConnection(conn
, query
)
291 response
= self
.recvTCPResponseOverConnection(conn
)
299 self
.assertEqual(count
, 0)