]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_TCPFastOpen.py
Merge pull request #8795 from omoerbeek/rec-lua-docs-policytag
[thirdparty/pdns.git] / regression-tests.dnsdist / test_TCPFastOpen.py
CommitLineData
1573e7b8
RG
1#!/usr/bin/env python
2import threading
3import clientsubnetoption
4import dns
5import requests
6import socket
7import struct
8from dnsdisttests import DNSDistTest
9
10class TestBrokenTCPFastOpen(DNSDistTest):
11
12 # this test suite uses a different responder port
13 # because, contrary to the other ones, its
14 # TCP responder will accept a connection, read the
15 # query then just close the connection right away
16 _testServerPort = 5410
17 _testServerRetries = 5
18 _webTimeout = 2.0
19 _webServerPort = 8083
20 _webServerBasicAuthPassword = 'secret'
21 _webServerAPIKey = 'apisecret'
22 _config_params = ['_testServerPort', '_testServerRetries', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey']
23 _config_template = """
24 newServer{address="127.0.0.1:%s", useClientSubnet=true, tcpFastOpen=true, retries=%d }
25 webserver("127.0.0.1:%s", "%s", "%s")
26 """
27
28 @classmethod
29 def BrokenTCPResponder(cls, port):
30 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
31 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
32 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
33 try:
34 sock.bind(("127.0.0.1", port))
35 except socket.error as e:
36 print("Error binding in the TCP responder: %s" % str(e))
37 sys.exit(1)
38
39 sock.listen(100)
40 while True:
41 (conn, _) = sock.accept()
42 conn.settimeout(5.0)
43 data = conn.recv(2)
44 if not data:
45 conn.close()
46 continue
47
48 (datalen,) = struct.unpack("!H", data)
49 data = conn.recv(datalen)
50 conn.close()
51 continue
52
53 sock.close()
54
55 @classmethod
56 def startResponders(cls):
57 print("Launching responders..")
58
59 # Normal responder
60 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
61 cls._UDPResponder.setDaemon(True)
62 cls._UDPResponder.start()
63
64 # Close the connection right after reading the query
65 cls._TCPResponder = threading.Thread(name='Broken TCP Responder', target=cls.BrokenTCPResponder, args=[cls._testServerPort])
66 cls._TCPResponder.setDaemon(True)
67 cls._TCPResponder.start()
68
69 def testTCOFastOpenOnCloseAfterRead(self):
70 """
71 TCP Fast Open: Close after read
72 """
73 name = 'close-after-read.tfo.tests.powerdns.com.'
74 query = dns.message.make_query(name, 'A', 'IN')
75
76 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
77 self.assertFalse(receivedQuery)
78 self.assertFalse(receivedResponse)
79
80 headers = {'x-api-key': self._webServerAPIKey}
81 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost'
82 r = requests.get(url, headers=headers, timeout=self._webTimeout)
83 self.assertTrue(r)
84 self.assertEquals(r.status_code, 200)
85 self.assertTrue(r.json())
86 content = r.json()
87 self.assertTrue(len(content['servers']), 1)
88 server = content['servers'][0]
89 self.assertIn('tcpDiedReadingResponse', server)
90 self.assertEquals(server['tcpDiedReadingResponse'], self._testServerRetries)