3 import clientsubnetoption
8 from dnsdisttests
import DNSDistTest
10 class TestBrokenTCPFastOpen(DNSDistTest
):
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
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")
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)
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
))
41 (conn
, _
) = sock
.accept()
48 (datalen
,) = struct
.unpack("!H", data
)
49 data
= conn
.recv(datalen
)
56 def startResponders(cls
):
57 print("Launching responders..")
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()
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()
69 def testTCOFastOpenOnCloseAfterRead(self
):
71 TCP Fast Open: Close after read
73 name
= 'close-after-read.tfo.tests.powerdns.com.'
74 query
= dns
.message
.make_query(name
, 'A', 'IN')
76 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
77 self
.assertFalse(receivedQuery
)
78 self
.assertFalse(receivedResponse
)
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
)
84 self
.assertEquals(r
.status_code
, 200)
85 self
.assertTrue(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
)