1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
|
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-or-later
# Run with "ninja kres-gen" to re-generate $1
set -o pipefail -o errexit -o nounset
cd "$(dirname ${0})"
OUTNAME="$1"
CDEFS="../../scripts/gen-cdefs.sh"
LIBKRES="${MESON_BUILD_ROOT}/lib/libkres.so"
KRESD="${MESON_BUILD_ROOT}/daemon/kresd"
if [ ! -e "$LIBKRES" ]; then
# We probably use static libkres.
LIBKRES="$KRESD"
fi
for REQFILE in "$CDEFS" "$LIBKRES" "$KRESD"
do
test '!' -s "$REQFILE" -a -r "$REQFILE" \
&& echo "Required file $REQFILE cannot be read, did you build binaries and shared libraries?" \
&& exit 1
done
# Write to "$OUTNAME" instead of stdout
mv "$OUTNAME"{,.bak} ||:
exec 5<&1- # move stdout into FD 5
exec 1<>"$OUTNAME" # replace stdout with file
restore() {
exec 1>&- # close stdout redirected into "$OUTNAME"
exec 1<&5- # restore original stdout
mv -v "$OUTNAME"{,.fail} ||:
mv -v "$OUTNAME"{.bak,} ||:
(>&2 echo "Failed to re-generate $OUTNAME! Missing debugsymbols? Missing shared library?")
}
trap restore ERR INT TERM
### Dev's guide
#
# C declarations for lua are (mostly) generated to simplify maintenance.
# (Avoid typos, accidental mismatches, etc.)
#
# To regenerate the C definitions for lua:
# - you need to have debugging symbols for knot-dns and knot-resolver;
# you get those by compiling with -g; for knot-dns it might be enough
# to just install it with debugging symbols included (in your distro way)
# - run ninja kres-gen
# - the knot-dns libraries are found via pkg-config
# - you also need gdb on $PATH
printf -- "-- SPDX-License-Identifier: GPL-3.0-or-later\n\n"
printf -- "local ffi = require('ffi')\n"
printf -- "--[[ This file is generated by ./kres-gen.sh ]] ffi.cdef[[\n"
# Some system dependencies. TODO: this generated part isn't perfectly portable.
${CDEFS} ${LIBKRES} types <<-EOF
typedef time_t
__time_t
__suseconds_t
struct timeval
EOF
## Various types (mainly), from libknot and libkres
printf "
typedef struct knot_dump_style knot_dump_style_t;
extern const knot_dump_style_t KR_DUMP_STYLE_DEFAULT;
struct kr_cdb_api {};
struct lru {};
"
${CDEFS} ${LIBKRES} types <<-EOF
knot_section_t
knot_rrinfo_t
knot_dname_t
knot_rdata_t
knot_rdataset_t
EOF
# The generator doesn't work well with typedefs of functions.
printf "
typedef struct knot_mm {
void *ctx, *alloc, *free;
} knot_mm_t;
typedef void *(*map_alloc_f)(void *, size_t);
typedef void (*map_free_f)(void *baton, void *ptr);
typedef void (*trace_log_f) (const struct kr_request *, const char *);
typedef void (*trace_callback_f)(struct kr_request *);
typedef uint8_t * (*alloc_wire_f)(struct kr_request *req, uint16_t *maxlen);
typedef bool (*addr_info_f)(struct sockaddr*);
typedef void (*zi_callback)(int state, void *param);
"
genResType() {
echo "$1" | ${CDEFS} ${LIBKRES} types
}
# No simple way to fixup this rename in ./kres.lua AFAIK.
genResType "knot_rrset_t" | sed 's/\<owner\>/_owner/; s/\<ttl\>/_ttl/'
printf "
struct kr_module;
typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *);
typedef unsigned char knot_dname_storage_t[255];
"
${CDEFS} ${LIBKRES} types <<-EOF
#knot_pkt_t contains indirect recursion
typedef knot_pkt_t
knot_edns_options_t
knot_pktsection_t
knot_compr_t
struct knot_pkt
#trie_t inside is private to libknot
typedef trie_t
# libkres
struct kr_qflags
ranked_rr_array_entry_t
ranked_rr_array_t
kr_http_header_array_entry_t
kr_http_header_array_t
kr_sockaddr_array_t
struct kr_zonecut
kr_qarray_t
struct kr_rplan
struct kr_request_qsource_flags
struct kr_extended_error
struct kr_request
enum kr_rank
typedef kr_cdb_pt
struct kr_cdb_stats
typedef uv_timer_t
struct kr_cache
# lib/layer.h
kr_layer_t
kr_layer_api_t
# lib/module.h
struct kr_prop
struct kr_module
struct kr_server_selection
kr_log_level_t
enum kr_log_group
EOF
# static variables; these lines might not be simple to generate
printf "
kr_layer_t kr_layer_t_static;
_Bool kr_dbg_assertion_abort;
int kr_dbg_assertion_fork;
"
printf "
typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
const struct kr_query *qry);
void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
uint16_t type, uint16_t rclass, uint32_t ttl);
"
## Some definitions would need too many deps, so shorten them.
genResType "struct kr_query"
genResType "struct kr_context" | sed '/module_array_t/,$ d'
printf "\tchar _stub[];\n};\n"
echo "struct kr_transport" | ${CDEFS} ${KRESD} types | sed '/union /,$ d'
printf "\t/* beware: hidden stub, to avoid hardcoding sockaddr lengths */\n};\n"
## libknot API
${CDEFS} libknot functions <<-EOF
# Utils
knot_strerror
# Domain names
knot_dname_copy
knot_dname_from_str
knot_dname_in_bailiwick
knot_dname_is_equal
knot_dname_labels
knot_dname_size
knot_dname_to_lower
knot_dname_to_str
# Resource records
knot_rdataset_at
knot_rdataset_merge
knot_rrset_add_rdata
knot_rrset_free
knot_rrset_txt_dump
knot_rrset_txt_dump_data
knot_rrset_size
# Packet
knot_pkt_begin
knot_pkt_put_question
knot_pkt_put_rotate
knot_pkt_new
knot_pkt_free
knot_pkt_parse
EOF
## libkres API
${CDEFS} ${LIBKRES} functions <<-EOF
# Resolution request
kr_request_ensure_edns
kr_request_ensure_answer
kr_request_set_extended_error
kr_resolve_plan
kr_resolve_pool
# Resolution plan
kr_rplan_push
kr_rplan_pop
kr_rplan_resolved
kr_rplan_last
# Forwarding
kr_forward_add_target
# Utils
kr_log_is_debug_fun
kr_log_req1
kr_log_q1
kr_log_grp2name
kr_log_fmt
kr_make_query
kr_pkt_make_auth_header
kr_pkt_put
kr_pkt_recycle
kr_pkt_clear_payload
kr_pkt_has_wire
kr_pkt_has_dnssec
kr_pkt_qclass
kr_pkt_qtype
kr_pkt_text
kr_rnd_buffered
kr_rrsig_sig_inception
kr_rrsig_sig_expiration
kr_rrsig_type_covered
kr_inaddr
kr_inaddr_family
kr_inaddr_len
kr_inaddr_str
kr_sockaddr_cmp
kr_sockaddr_len
kr_inaddr_port
kr_straddr_family
kr_straddr_subnet
kr_bitcmp
kr_family_len
kr_straddr_socket
kr_straddr_split
kr_rank_test
kr_ranked_rrarray_add
kr_ranked_rrarray_finalize
kr_qflags_set
kr_qflags_clear
kr_zonecut_add
kr_zonecut_is_empty
kr_zonecut_set
kr_now
kr_strptime_diff
kr_file_mtime
kr_fssize
kr_dirent_name
lru_free_items_impl
lru_create_impl
lru_get_impl
mm_realloc
# Trust anchors
kr_ta_get
kr_ta_add
kr_ta_del
kr_ta_clear
# DNSSEC
kr_dnssec_key_ksk
kr_dnssec_key_revoked
kr_dnssec_key_tag
kr_dnssec_key_match
# Cache
kr_cache_closest_apex
kr_cache_insert_rr
kr_cache_remove
kr_cache_remove_subtree
kr_cache_commit
# FIXME: perhaps rename this exported symbol
packet_ttl
EOF
## kresd itself: worker stuff
${CDEFS} ${KRESD} types <<-EOF
endpoint_flags_t
# struct args is a bit complex
addr_array_t
flagged_fd_t
flagged_fd_array_t
config_array_t
struct args
zi_config_t
EOF
echo "struct args *the_args;"
echo "struct endpoint" | ${CDEFS} ${KRESD} types | sed 's/uv_handle_t \*/void */'
echo "struct request_ctx" | ${CDEFS} ${KRESD} types | sed '/struct {/,$ d'
printf "\t/* beware: hidden stub, to avoid hardcoding sockaddr lengths */\n};\n"
echo "struct qr_task" | ${CDEFS} ${KRESD} types | sed '/pktbuf/,$ d'
printf "\t/* beware: hidden stub, to avoid qr_tasklist_t */\n};\n"
${CDEFS} ${KRESD} functions <<-EOF
worker_resolve_exec
worker_resolve_mk_pkt
worker_resolve_start
zi_zone_import
EOF
echo "struct engine" | ${CDEFS} ${KRESD} types | sed '/struct network/,$ d'
printf "\tchar _stub[];\n};\n"
echo "struct worker_ctx" | ${CDEFS} ${KRESD} types | sed '/uv_loop_t/,$ d'
printf "\tchar _stub[];\n};\n"
echo "struct worker_ctx *the_worker;"
## libzscanner API for ./zonefile.lua
if pkg-config libknot --atleast-version=3.1; then
echo "zs_svcb_t" | ${CDEFS} libzscanner types
fi
${CDEFS} libzscanner types <<-EOF
zs_win_t
zs_apl_t
zs_loc_t
zs_state_t
#zs_scanner_t contains recursion
typedef zs_scanner_t
zs_scanner_t
EOF
${CDEFS} libzscanner functions <<-EOF
zs_deinit
zs_init
zs_parse_record
zs_set_input_file
zs_set_input_string
zs_strerror
EOF
printf "]]\n"
rm "$OUTNAME".bak ||:
(>&2 echo "Successfully re-generated ${PWD}/$OUTNAME")
exit 0
|