Mercurial > prosody-hg
comparison net/unbound.lua @ 14210:41fa97090264
Merge 13.0->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 30 May 2026 19:22:51 +0200 |
| parents | 350e16e5f9aa c4aa9b2b4787 |
| children | 2719dbb358c8 |
comparison
equal
deleted
inserted
replaced
| 14206:2b13c24ba2d6 | 14210:41fa97090264 |
|---|---|
| 17 local log = logger.init("unbound"); | 17 local log = logger.init("unbound"); |
| 18 local net_server = require "prosody.net.server"; | 18 local net_server = require "prosody.net.server"; |
| 19 local libunbound = require"lunbound"; | 19 local libunbound = require"lunbound"; |
| 20 local promise = require"prosody.util.promise"; | 20 local promise = require"prosody.util.promise"; |
| 21 local new_id = require "prosody.util.id".short; | 21 local new_id = require "prosody.util.id".short; |
| 22 local timer = require "prosody.util.timer"; | |
| 22 | 23 |
| 23 local dns_utils = require"prosody.util.dns"; | 24 local dns_utils = require"prosody.util.dns"; |
| 24 local classes, types, errors = dns_utils.classes, dns_utils.types, dns_utils.errors; | 25 local classes, types, errors = dns_utils.classes, dns_utils.types, dns_utils.errors; |
| 25 local parsers = dns_utils.parsers; | 26 local parsers = dns_utils.parsers; |
| 26 | 27 |
| 40 end | 41 end |
| 41 return conf; | 42 return conf; |
| 42 end | 43 end |
| 43 | 44 |
| 44 local unbound_config; | 45 local unbound_config; |
| 45 if prosody then | |
| 46 local config = require"prosody.core.configmanager"; | |
| 47 unbound_config = add_defaults(config.get("*", "unbound")); | |
| 48 prosody.events.add_handler("config-reloaded", function() | |
| 49 unbound_config = add_defaults(config.get("*", "unbound")); | |
| 50 end); | |
| 51 end | |
| 52 -- Note: libunbound will default to using root hints if resolvconf is unset | 46 -- Note: libunbound will default to using root hints if resolvconf is unset |
| 53 | 47 |
| 54 local function connect_server(unbound, server) | 48 local function connect_server(unbound, server) |
| 55 log("debug", "Setting up net.server event handling for %s", unbound); | 49 log("debug", "Setting up net.server event handling for %s", unbound); |
| 56 return server.watchfd(unbound, function () | 50 return server.watchfd(unbound, function () |
| 62 local unbound, server_conn; | 56 local unbound, server_conn; |
| 63 | 57 |
| 64 local function initialize() | 58 local function initialize() |
| 65 unbound = libunbound.new(unbound_config); | 59 unbound = libunbound.new(unbound_config); |
| 66 server_conn = connect_server(unbound, net_server); | 60 server_conn = connect_server(unbound, net_server); |
| 67 end | |
| 68 if prosody then | |
| 69 prosody.events.add_handler("server-started", initialize); | |
| 70 end | 61 end |
| 71 | 62 |
| 72 local answer_mt = { | 63 local answer_mt = { |
| 73 __tostring = function(self) | 64 __tostring = function(self) |
| 74 if self._string then return self._string end | 65 if self._string then return self._string end |
| 89 local _string = t_concat(t, "\n"); | 80 local _string = t_concat(t, "\n"); |
| 90 self._string = _string; | 81 self._string = _string; |
| 91 return _string; | 82 return _string; |
| 92 end; | 83 end; |
| 93 }; | 84 }; |
| 94 | |
| 95 local waiting_queries = {}; | |
| 96 | 85 |
| 97 local function prep_answer(a) | 86 local function prep_answer(a) |
| 98 if not a then return end | 87 if not a then return end |
| 99 local status = errors[a.rcode]; | 88 local status = errors[a.rcode]; |
| 100 local qclass = classes[a.qclass]; | 89 local qclass = classes[a.qclass]; |
| 126 qtype = qtype and s_upper(qtype) or "A"; | 115 qtype = qtype and s_upper(qtype) or "A"; |
| 127 qclass = qclass and s_upper(qclass) or "IN"; | 116 qclass = qclass and s_upper(qclass) or "IN"; |
| 128 local ntype, nclass = types[qtype], classes[qclass]; | 117 local ntype, nclass = types[qtype], classes[qclass]; |
| 129 | 118 |
| 130 local m; | 119 local m; |
| 131 local ret; | |
| 132 local log_query = logger.init("unbound.query"..new_id()); | 120 local log_query = logger.init("unbound.query"..new_id()); |
| 133 local function callback_wrapper(a, err) | 121 local function callback_wrapper(a, err) |
| 134 m(); | 122 m(); |
| 135 waiting_queries[ret] = nil; | |
| 136 if a then | 123 if a then |
| 137 count(qclass, qtype, #a); | 124 count(qclass, qtype, #a); |
| 138 prep_answer(a); | 125 prep_answer(a); |
| 139 log_query("debug", "Results for %s %s %s: %s (%s)", qname, qclass, qtype, a.rcode == 0 and (#a .. " items") or a.status, | 126 log_query("debug", "Results for %s %s %s: %s (%s)", qname, qclass, qtype, a.rcode == 0 and (#a .. " items") or a.status, |
| 140 a.secure and "Secure" or a.bogus or "Insecure"); -- Insecure as in unsigned | 127 a.secure and "Secure" or a.bogus or "Insecure"); -- Insecure as in unsigned |
| 144 local ok, cerr = pcall(callback, a, err); | 131 local ok, cerr = pcall(callback, a, err); |
| 145 if not ok then log_query("error", "Error in callback: %s", cerr); end | 132 if not ok then log_query("error", "Error in callback: %s", cerr); end |
| 146 end | 133 end |
| 147 log_query("debug", "Resolve %s %s %s", qname, qclass, qtype); | 134 log_query("debug", "Resolve %s %s %s", qname, qclass, qtype); |
| 148 m = measure(qclass, qtype); | 135 m = measure(qclass, qtype); |
| 149 local err; | 136 local ret, err = unbound:resolve_async(callback_wrapper, qname, ntype, nclass); |
| 150 ret, err = unbound:resolve_async(callback_wrapper, qname, ntype, nclass); | 137 if not ret then |
| 151 if ret then | |
| 152 waiting_queries[ret] = callback; | |
| 153 else | |
| 154 log_query("error", "Resolver error: %s", err); | 138 log_query("error", "Resolver error: %s", err); |
| 155 end | 139 end |
| 156 return ret, err; | 140 return ret, err; |
| 157 end | 141 end |
| 158 | 142 |
| 164 local a, err = unbound:resolve(qname, ntype, nclass); | 148 local a, err = unbound:resolve(qname, ntype, nclass); |
| 165 if not a then return a, err; end | 149 if not a then return a, err; end |
| 166 return prep_answer(a); | 150 return prep_answer(a); |
| 167 end | 151 end |
| 168 | 152 |
| 169 local function cancel(id) | |
| 170 local cb = waiting_queries[id]; | |
| 171 unbound:cancel(id); | |
| 172 if cb then | |
| 173 cb(nil, "canceled"); | |
| 174 waiting_queries[id] = nil; | |
| 175 end | |
| 176 return true; | |
| 177 end | |
| 178 | |
| 179 -- Reinitiate libunbound context, drops cache | 153 -- Reinitiate libunbound context, drops cache |
| 180 local function purge() | 154 local function purge() |
| 181 for id in pairs(waiting_queries) do cancel(id); end | 155 if server_conn then |
| 182 if server_conn then server_conn:close(); end | 156 local old_unbound, old_server_conn = unbound, server_conn; |
| 157 timer.add_task(30, function() | |
| 158 old_server_conn:close(); | |
| 159 if old_unbound.cancelall then | |
| 160 old_unbound:cancelall(); | |
| 161 end | |
| 162 end) | |
| 163 end | |
| 183 initialize(); | 164 initialize(); |
| 184 return true; | 165 return true; |
| 166 end | |
| 167 | |
| 168 if prosody then | |
| 169 local config = require"prosody.core.configmanager"; | |
| 170 unbound_config = add_defaults(config.get("*", "unbound")); | |
| 171 prosody.events.add_handler("config-reloaded", function() | |
| 172 unbound_config = add_defaults(config.get("*", "unbound")); | |
| 173 purge(); | |
| 174 end); | |
| 175 prosody.events.add_handler("server-started", initialize); | |
| 185 end | 176 end |
| 186 | 177 |
| 187 local function not_implemented() | 178 local function not_implemented() |
| 188 error "not implemented"; | 179 error "not implemented"; |
| 189 end | 180 end |
| 190 -- Public API | 181 -- Public API |
| 191 local _M = { | 182 local _M = { |
| 192 lookup = lookup; | 183 lookup = lookup; |
| 193 cancel = cancel; | 184 cancel = not_implemented; |
| 194 new_async_socket = not_implemented; | 185 new_async_socket = not_implemented; |
| 195 dns = { | 186 dns = { |
| 196 lookup = lookup_sync; | 187 lookup = lookup_sync; |
| 197 cancel = cancel; | 188 cancel = not_implemented; |
| 198 cache = noop; | 189 cache = noop; |
| 199 socket_wrapper_set = noop; | 190 socket_wrapper_set = noop; |
| 200 settimeout = noop; | 191 settimeout = noop; |
| 201 query = noop; | 192 query = noop; |
| 202 purge = purge; | 193 purge = purge; |
