Commit b99df087 authored by Petr Špaček's avatar Petr Špaček

doh: make client and server address available to modules

This will allow modules like view etc. work in the same way with packets
received over HTTP.
parent 8f1155b8
......@@ -312,6 +312,7 @@ const char *kr_inaddr(const struct sockaddr *);
int kr_inaddr_family(const struct sockaddr *);
int kr_inaddr_len(const struct sockaddr *);
int kr_inaddr_str(const struct sockaddr *, char *, size_t *);
int kr_sockaddr_cmp(const struct sockaddr *, const struct sockaddr *);
int kr_sockaddr_len(const struct sockaddr *);
uint16_t kr_inaddr_port(const struct sockaddr *);
int kr_straddr_family(const char *);
......
......@@ -174,6 +174,7 @@ ${CDEFS} ${LIBKRES} functions <<-EOF
kr_inaddr_family
kr_inaddr_len
kr_inaddr_str
kr_sockaddr_cmp
kr_sockaddr_len
kr_inaddr_port
kr_straddr_family
......
......@@ -8,6 +8,13 @@ local function get_http_ttl(pkt)
return ffi.C.packet_ttl(pkt, is_negative)
end
local function convert_sockaddr(family, ipaddr, port)
if not (family and ipaddr and port) then
panic('failed to obtain peer IP address')
end
return ffi.gc(ffi.C.kr_straddr_socket(ipaddr, port), ffi.C.free)
end
-- Trace execution of DNS queries
local function serve_doh(h, stream)
local input
......@@ -81,8 +88,14 @@ local function serve_doh(h, stream)
end
print(pkt)
-- set source address so filters can work
local function init_cb(req)
req.qsource.addr = convert_sockaddr(stream:peername())
req.qsource.dst_addr = convert_sockaddr(stream:localname())
end
-- resolve query
worker.resolve_pkt(pkt, finish_cb)
worker.resolve_pkt(pkt, finish_cb, init_cb)
-- Wait for asynchronous query and free callbacks -- FIXME
if not done then
waiting = true
......
......@@ -178,6 +178,47 @@ else
check_err(req, '415', 'unsupported request content type finishes with 415')
end
local function test_dstaddr()
local triggered = false
local exp_dstaddr = ffi.gc(ffi.C.kr_straddr_socket(host, port), ffi.C.free)
local function check_dstaddr(state, req)
triggered = true
print(exp_dstaddr)
print(req.qsource.dst_addr)
same(ffi.C.kr_sockaddr_cmp(req.qsource.dst_addr, exp_dstaddr), 0,
'request has correct server address')
return state
end
policy.add(policy.suffix(check_dstaddr, policy.todnames({'dstaddr.test'})))
local desc = 'valid POST query has server address available in request'
local req = req_templ:clone()
req.headers:upsert(':method', 'POST')
req:set_body(basexx.from_base64( -- dstaddr.test. A
'FnkBAAABAAAAAAAAB2RzdGFkZHIEdGVzdAAAAQAB'))
check_ok(req, desc)
ok(triggered, 'dstaddr policy was triggered')
end
local function test_srcaddr()
modules.load('view')
assert(view)
local policy_refuse = policy.suffix(policy.REFUSE, policy.todnames({'srcaddr.test.knot-resolver.cz'}))
-- these netmasks would not work if the request did not contain IP addresses
view:addr('0.0.0.0/0', policy_refuse)
view:addr('::/0', policy_refuse)
local desc = 'valid POST query has source address available in request'
local req = req_templ:clone()
req.headers:upsert(':method', 'POST')
req:set_body(basexx.from_base64( -- srcaddr.test.knot-resolver.cz TXT
'QNQBAAABAAAAAAAAB3NyY2FkZHIEdGVzdA1rbm90LXJlc29sdmVyAmN6AAAQAAE'))
headers, pkt = check_ok(req, desc)
same(pkt:rcode(), kres.rcode.REFUSED, desc .. ': view module caught it')
modules.unload('view')
end
-- not implemented
-- local function test_post_unsupp_accept()
-- local req = assert(req_templ:clone())
......@@ -197,7 +238,9 @@ else
test_post_unsupp_type,
test_doh_servfail,
test_doh_nxdomain,
test_doh_noerror
test_doh_noerror,
test_dstaddr,
test_srcaddr
}
return tests
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment