]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_LuaFFI.py
5 from dnsdisttests
import DNSDistTest
7 class TestAdvancedLuaFFI ( DNSDistTest
):
10 local ffi = require("ffi")
12 local expectingUDP = true
14 function luaffirulefunction(dq)
15 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
16 if qtype ~= DNSQType.A and qtype ~= DNSQType.SOA then
17 print('invalid qtype')
21 local qclass = ffi.C.dnsdist_ffi_dnsquestion_get_qclass(dq)
22 if qclass ~= DNSClass.IN then
23 print('invalid qclass')
27 local ret_ptr = ffi.new("char *[1]")
28 local ret_ptr_param = ffi.cast("const char **", ret_ptr)
29 local ret_size = ffi.new("size_t[1]")
30 local ret_size_param = ffi.cast("size_t*", ret_size)
31 ffi.C.dnsdist_ffi_dnsquestion_get_qname_raw(dq, ret_ptr_param, ret_size_param)
32 if ret_size[0] ~= 36 then
33 print('invalid length for the qname ')
38 local expectedQname = string.char(6)..'luaffi'..string.char(8)..'advanced'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com'
39 if ffi.string(ret_ptr[0]) ~= expectedQname then
40 print('invalid qname')
41 print(ffi.string(ret_ptr[0]))
45 local rcode = ffi.C.dnsdist_ffi_dnsquestion_get_rcode(dq)
47 print('invalid rcode')
51 local opcode = ffi.C.dnsdist_ffi_dnsquestion_get_opcode(dq)
52 if qtype == DNSQType.A and opcode ~= DNSOpcode.Query then
53 print('invalid opcode')
55 elseif qtype == DNSQType.SOA and opcode ~= DNSOpcode.Update then
56 print('invalid opcode')
60 local tcp = ffi.C.dnsdist_ffi_dnsquestion_get_tcp(dq)
61 if expectingUDP == tcp then
65 expectingUDP = expectingUDP == false
67 local dnssecok = ffi.C.dnsdist_ffi_dnsquestion_get_do(dq)
68 if dnssecok ~= false then
69 print('invalid DNSSEC OK')
73 local len = ffi.C.dnsdist_ffi_dnsquestion_get_len(dq)
75 print('invalid length')
80 local tag = ffi.C.dnsdist_ffi_dnsquestion_get_tag(dq, 'a-tag')
81 if ffi.string(tag) ~= 'a-value' then
82 print('invalid tag value')
83 print(ffi.string(tag))
87 local raw_tag_buf_size = 255
88 local raw_tag_buf = ffi.new("char [?]", raw_tag_buf_size)
89 local raw_tag_size = ffi.C.dnsdist_ffi_dnsquestion_get_tag_raw(dq, 'raw-tag', raw_tag_buf, raw_tag_buf_size)
90 if ffi.string(raw_tag_buf, raw_tag_size) ~= 'a\0b' then
91 print('invalid raw tag value')
92 print(ffi.string(raw_tag_buf, raw_tag_size))
99 function luaffiactionfunction(dq)
100 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
101 if qtype == DNSQType.A then
102 local str = "192.0.2.1"
103 local buf = ffi.new("char[?]", #str + 1)
105 ffi.C.dnsdist_ffi_dnsquestion_set_result(dq, buf, #str)
106 return DNSAction.Spoof
107 elseif qtype == DNSQType.SOA then
108 ffi.C.dnsdist_ffi_dnsquestion_set_rcode(dq, DNSRCode.REFUSED)
109 return DNSAction.Refused
113 function luaffiactionsettag(dq)
114 ffi.C.dnsdist_ffi_dnsquestion_set_tag(dq, 'a-tag', 'a-value')
115 return DNSAction.None
118 function luaffiactionsettagraw(dq)
120 ffi.C.dnsdist_ffi_dnsquestion_set_tag_raw(dq, 'raw-tag', value, #value)
121 return DNSAction.None
124 addAction(AllRule(), LuaFFIAction(luaffiactionsettag))
125 addAction(AllRule(), LuaFFIAction(luaffiactionsettagraw))
126 addAction(LuaFFIRule(luaffirulefunction), LuaFFIAction(luaffiactionfunction))
127 -- newServer{address="127.0.0.1: %d "}
130 def testAdvancedLuaFFI ( self
):
132 Lua FFI: Test the Lua FFI interface
134 name
= 'luaffi.advanced.tests.powerdns.com.'
135 query
= dns
. message
. make_query ( name
, 'A' , 'IN' )
136 # dnsdist set RA = RD for spoofed responses
137 query
. flags
&= ~dns
. flags
. RD
139 response
= dns
. message
. make_response ( query
)
140 rrset
= dns
. rrset
. from_text ( name
,
145 response
. answer
. append ( rrset
)
147 for method
in ( "sendUDPQuery" , "sendTCPQuery" ):
148 sender
= getattr ( self
, method
)
149 ( _
, receivedResponse
) = sender ( query
, response
= None , useQueue
= False )
150 self
. assertEqual ( receivedResponse
, response
)
152 def testAdvancedLuaFFIUpdate ( self
):
154 Lua FFI: Test the Lua FFI interface via an update
156 name
= 'luaffi.advanced.tests.powerdns.com.'
157 query
= dns
. message
. make_query ( name
, 'SOA' , 'IN' )
158 query
. set_opcode ( dns
. opcode
. UPDATE
)
159 # dnsdist set RA = RD for spoofed responses
160 query
. flags
&= ~dns
. flags
. RD
162 response
= dns
. message
. make_response ( query
)
163 response
. set_rcode ( dns
. rcode
. REFUSED
)
165 for method
in ( "sendUDPQuery" , "sendTCPQuery" ):
166 sender
= getattr ( self
, method
)
167 ( _
, receivedResponse
) = sender ( query
, response
= None , useQueue
= False )
168 self
. assertEqual ( receivedResponse
, response
)
170 class TestAdvancedLuaFFIPerThread ( DNSDistTest
):
172 _config_template
= """
174 local rulefunction = [[
175 local ffi = require("ffi")
178 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
179 if qtype ~= DNSQType.A and qtype ~= DNSQType.SOA then
180 print('invalid qtype')
184 local qclass = ffi.C.dnsdist_ffi_dnsquestion_get_qclass(dq)
185 if qclass ~= DNSClass.IN then
186 print('invalid qclass')
190 local ret_ptr = ffi.new("char *[1]")
191 local ret_ptr_param = ffi.cast("const char **", ret_ptr)
192 local ret_size = ffi.new("size_t[1]")
193 local ret_size_param = ffi.cast("size_t*", ret_size)
194 ffi.C.dnsdist_ffi_dnsquestion_get_qname_raw(dq, ret_ptr_param, ret_size_param)
195 if ret_size[0] ~= 45 then
196 print('invalid length for the qname ')
201 local expectedQname = string.char(15)..'luaffiperthread'..string.char(8)..'advanced'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com'
202 if ffi.string(ret_ptr[0]) ~= expectedQname then
203 print('invalid qname')
204 print(ffi.string(ret_ptr[0]))
208 local rcode = ffi.C.dnsdist_ffi_dnsquestion_get_rcode(dq)
210 print('invalid rcode')
214 local opcode = ffi.C.dnsdist_ffi_dnsquestion_get_opcode(dq)
215 if qtype == DNSQType.A and opcode ~= DNSOpcode.Query then
216 print('invalid opcode')
218 elseif qtype == DNSQType.SOA and opcode ~= DNSOpcode.Update then
219 print('invalid opcode')
223 local dnssecok = ffi.C.dnsdist_ffi_dnsquestion_get_do(dq)
224 if dnssecok ~= false then
225 print('invalid DNSSEC OK')
229 local len = ffi.C.dnsdist_ffi_dnsquestion_get_len(dq)
231 print('invalid length')
236 local tag = ffi.C.dnsdist_ffi_dnsquestion_get_tag(dq, 'a-tag')
237 if ffi.string(tag) ~= 'a-value' then
238 print('invalid tag value')
239 print(ffi.string(tag))
247 local actionfunction = [[
248 local ffi = require("ffi")
251 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
252 if qtype == DNSQType.A then
253 local str = "192.0.2.1"
254 local buf = ffi.new("char[?]", #str + 1)
256 ffi.C.dnsdist_ffi_dnsquestion_set_result(dq, buf, #str)
257 return DNSAction.Spoof
258 elseif qtype == DNSQType.SOA then
259 ffi.C.dnsdist_ffi_dnsquestion_set_rcode(dq, DNSRCode.REFUSED)
260 return DNSAction.Refused
265 local settagfunction = [[
266 local ffi = require("ffi")
269 ffi.C.dnsdist_ffi_dnsquestion_set_tag(dq, 'a-tag', 'a-value')
270 return DNSAction.None
274 addAction(AllRule(), LuaFFIPerThreadAction(settagfunction))
275 addAction(LuaFFIPerThreadRule(rulefunction), LuaFFIPerThreadAction(actionfunction))
276 -- newServer{address="127.0.0.1: %d "}
279 def testAdvancedLuaPerthreadFFI ( self
):
281 Lua FFI: Test the Lua FFI per-thread interface
283 name
= 'luaffiperthread.advanced.tests.powerdns.com.'
284 query
= dns
. message
. make_query ( name
, 'A' , 'IN' )
285 # dnsdist set RA = RD for spoofed responses
286 query
. flags
&= ~dns
. flags
. RD
288 response
= dns
. message
. make_response ( query
)
289 rrset
= dns
. rrset
. from_text ( name
,
294 response
. answer
. append ( rrset
)
296 for method
in ( "sendUDPQuery" , "sendTCPQuery" ):
297 sender
= getattr ( self
, method
)
298 ( _
, receivedResponse
) = sender ( query
, response
= None , useQueue
= False )
299 self
. assertEqual ( receivedResponse
, response
)
301 def testAdvancedLuaFFIPerThreadUpdate ( self
):
303 Lua FFI: Test the Lua FFI per-thread interface via an update
305 name
= 'luaffiperthread.advanced.tests.powerdns.com.'
306 query
= dns
. message
. make_query ( name
, 'SOA' , 'IN' )
307 query
. set_opcode ( dns
. opcode
. UPDATE
)
308 # dnsdist set RA = RD for spoofed responses
309 query
. flags
&= ~dns
. flags
. RD
311 response
= dns
. message
. make_response ( query
)
312 response
. set_rcode ( dns
. rcode
. REFUSED
)
314 for method
in ( "sendUDPQuery" , "sendTCPQuery" ):
315 sender
= getattr ( self
, method
)
316 ( _
, receivedResponse
) = sender ( query
, response
= None , useQueue
= False )
317 self
. assertEqual ( receivedResponse
, response
)
319 class TestLuaFFIHeader ( DNSDistTest
):
321 _config_template
= """
322 local bit = require("bit")
323 local ffi = require("ffi")
325 -- check that the AA bit is clear, set the rcode to REFUSED otherwise
326 function checkAAResponseAction(dr)
327 local header_void = ffi.C.dnsdist_ffi_dnsquestion_get_header(dr)
328 local header = ffi.cast("unsigned char *", header_void)
330 local aa = bit.band(header[2], bit.lshift(1, 2)) ~= 0
332 ffi.C.dnsdist_ffi_dnsquestion_set_rcode(dr, DNSRCode.REFUSED)
333 -- prevent subsequent rules from being applied
334 return DNSResponseAction.HeaderModify
336 return DNSResponseAction.None
339 -- set the AA bit to 1
340 function setAAResponseAction(dr)
341 local header_void = ffi.C.dnsdist_ffi_dnsquestion_get_header(dr)
342 local header = ffi.cast("unsigned char *", header_void)
344 header[2] = bit.bor(header[2], bit.lshift(1, 2))
345 return DNSResponseAction.None
348 addResponseAction(AllRule(), LuaFFIResponseAction(checkAAResponseAction))
349 addResponseAction(AllRule(), LuaFFIResponseAction(setAAResponseAction))
350 newServer{address="127.0.0.1: %d "}
353 def testLuaFFISetAAHeader ( self
):
357 name
= 'dnsheader-set-aa.luaffi.tests.powerdns.com.'
358 query
= dns
. message
. make_query ( name
, 'A' , 'IN' )
360 response
= dns
. message
. make_response ( query
)
361 rrset
= dns
. rrset
. from_text ( name
,
366 response
. answer
. append ( rrset
)
367 expectedResponse
= dns
. message
. make_response ( query
)
368 rrset
= dns
. rrset
. from_text ( name
,
373 expectedResponse
. answer
. append ( rrset
)
374 expectedResponse
. flags |
= dns
. flags
. AA
376 for method
in ( "sendUDPQuery" , "sendTCPQuery" ):
377 sender
= getattr ( self
, method
)
378 ( receivedQuery
, receivedResponse
) = sender ( query
, response
)
379 receivedQuery
. id = query
. id
380 self
. assertEqual ( query
, receivedQuery
)
381 self
. assertEqual ( expectedResponse
, receivedResponse
)
383 def testLuaFFIGetAAHeader ( self
):
385 Lua FFI: check AA=0, return REFUSED otherwise
387 name
= 'dnsheader-get-aa.luaffi.tests.powerdns.com.'
388 query
= dns
. message
. make_query ( name
, 'A' , 'IN' )
390 response
= dns
. message
. make_response ( query
)
391 rrset
= dns
. rrset
. from_text ( name
,
396 response
. answer
. append ( rrset
)
397 response
. flags |
= dns
. flags
. AA
398 expectedResponse
= dns
. message
. make_response ( query
)
399 expectedResponse
. flags |
= dns
. flags
. AA
400 expectedResponse
. set_rcode ( dns
. rcode
. REFUSED
)
401 expectedResponse
. answer
. append ( rrset
)
403 for method
in ( "sendUDPQuery" , "sendTCPQuery" ):
404 sender
= getattr ( self
, method
)
405 ( receivedQuery
, receivedResponse
) = sender ( query
, response
)
406 receivedQuery
. id = query
. id
407 self
. assertEqual ( query
, receivedQuery
)
408 self
. assertEqual ( expectedResponse
, receivedResponse
)