summaryrefslogtreecommitdiffstats
path: root/daemon/lua/kres-gen.sh
blob: 70afb408b297e81185313c50ecc478d2ad030da1 (plain)
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