Lewati ke konten utama

mudfish_dns_module.h

Unduh mudfish_dns_module.h dan letakkan bersama sumber C modul. Berikut header lengkap dari Mudfish DNS, termasuk deklarasi kompatibilitas. Gunakan C ABI v2 untuk modul dalam panduan ini.

Contoh policy.c menyediakan perintah build dan contoh perilaku DNS. Lihat Modul native untuk pemuatan, perilaku hook, dan kepemilikan buffer.

Tipe yang digunakan modul v2​

TipeKegunaan
mudfish_dns_spanPointer dan panjang input pinjaman atau respons pengganti milik modul. String tidak diakhiri NUL.
mudfish_dns_eventData wire kueri dan respons DNS, sumber respons, tujuan asli, dan status kebijakan domain yang ada.
mudfish_dns_web_eventData web, Host/SNI, tujuan, protokol, arah, dan status kebijakan domain yang ada. Data HTTPS tetap terenkripsi.
mudfish_dns_resultTindakan DNS serta alamat respons, TTL, atau respons pengganti opsional.
mudfish_dns_module_v2Konteks modul, callback DNS/web opsional, dan callback pembersihan.

Ekspor mudfish_dns_module_init_v2() dengan signature berikut. Host memulai dengan semua field modul bernilai NULL. Periksa versi ABI dan ukuran struktur sebelum menulis field. Biarkan hook yang tidak digunakan NULL dan kembalikan 0 saat berhasil.

Jika inisialisasi gagal, bersihkan sendiri sumber daya yang dialokasikan. Jika berhasil, host memanggil destroy() sekali ketika modul tidak lagi digunakan, sebelum melepas pustaka. Hentikan thread milik modul dan tunggu sampai selesai di sini.

Header lengkap​

mudfish_dns_module.h
#ifndef MUDFISH_DNS_MODULE_H
#define MUDFISH_DNS_MODULE_H

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define MUDFISH_DNS_MODULE_ABI_V1 1
#define MUDFISH_DNS_MODULE_ABI_V2 2
#define MUDFISH_DNS_CONTINUE 0
#define MUDFISH_DNS_REJECT 1
#define MUDFISH_DNS_BLOCK MUDFISH_DNS_REJECT
#define MUDFISH_DNS_ALLOW 2
#define MUDFISH_DNS_DROP 3
#define MUDFISH_DNS_ANSWER 4
#define MUDFISH_DNS_REPLACE 5

#define MUDFISH_DNS_IPV4 4
#define MUDFISH_DNS_IPV6 6

#define MUDFISH_DNS_SOURCE_QUERY 0
#define MUDFISH_DNS_SOURCE_UPSTREAM 1
#define MUDFISH_DNS_SOURCE_CACHE 2
#define MUDFISH_DNS_SOURCE_ORIGINAL 3
#define MUDFISH_DNS_SOURCE_ERROR 4
#define MUDFISH_DNS_SOURCE_MODULE 5

#define MUDFISH_DNS_WEB_UNKNOWN 0
#define MUDFISH_DNS_WEB_HTTP 1
#define MUDFISH_DNS_WEB_HTTPS 2
#define MUDFISH_DNS_TO_SERVER 1
#define MUDFISH_DNS_TO_CLIENT 2

/* Input spans are borrowed for this callback only; strings are not NUL terminated.
* Empty spans have length zero and must not be dereferenced. Never mutate, free,
* or retain any host pointer. DNS messages use wire format without TCP framing.
*/
struct mudfish_dns_span {
const uint8_t *data;
size_t len;
};

struct mudfish_dns_event {
struct mudfish_dns_span query;
struct mudfish_dns_span response; /* Empty in on_dns_query. */
struct mudfish_dns_span original_destination; /* IP:port, empty for loopback. */
uint32_t source;
uint32_t applied; /* Existing domain policy selects protected resolution. */
};

struct mudfish_dns_web_event {
struct mudfish_dns_span data;
struct mudfish_dns_span hostname; /* Normalized Host/SNI, or empty. */
struct mudfish_dns_span destination; /* IP:port. */
uint32_t protocol;
uint32_t direction;
uint32_t applied; /* Existing domain policy selects web protection. */
};

/* Return CONTINUE or REJECT. Any other value fails the request/connection.
* Hooks run in load order and stop at the first non-CONTINUE result.
* Calls for one module instance are serialized, but may use different threads.
* Hooks must finish promptly, must not unwind/longjmp across the ABI, and must
* not call back into the host. HTTPS data is encrypted; no TLS termination.
*/
struct mudfish_dns_module_v1 {
void *context;
int32_t (*on_dns_query)(void *, const struct mudfish_dns_event *);
int32_t (*on_dns_response)(void *, const struct mudfish_dns_event *);
int32_t (*on_web_hello)(void *, const struct mudfish_dns_web_event *);
int32_t (*on_web_data)(void *, const struct mudfish_dns_web_event *);
void (*destroy)(void *);
};

/* Export this exact symbol. The host initializes all fields to NULL.
* Check abi_version and module_size before writing. NULL hooks are optional.
* The output pointer is valid only during init. Return zero on success.
* On failure, clean up your own resources; the host will not call destroy.
* On success, destroy runs once after all users finish, before dlclose. Any
* module-owned threads must stop/join in destroy. Module code runs with the
* service's privileges and must satisfy this contract, including constructors.
*/
int32_t mudfish_dns_module_init_v1(uint32_t abi_version, size_t module_size,
struct mudfish_dns_module_v1 *module);

/* DNS v2 hooks return zero on success, nonzero on error (SERVFAIL).
* The host zeroes result before each call. Set action to:
* CONTINUE: consult the next module, then use the existing resolution/response.
* ALLOW: stop this hook chain and use the existing resolution/response.
* BLOCK: stop this hook chain and return REFUSED.
* DROP: discard this query/response without sending any DNS response.
* ANSWER: replace the response with the IP below, without upstream resolution
* when used in on_dns_query. IPv4 produces A, IPv6 produces AAAA.
* Other question types/classes get empty NOERROR (including an address
* family mismatch); IN/ANY gets the selected address record.
* REPLACE: use result.response as the complete DNS wire response. Valid in
* either DNS hook. The ID, opcode and question must match the query.
* Unknown actions or invalid ANSWER address families fail with SERVFAIL.
* Query results except DROP still pass through the response hook chain.
* Response decisions are final and never invoke response hooks recursively.
* Synthetic/replaced responses are not stored in the host cache.
* The host clears AD on replacements; modules must remove stale DNSSEC records
* when modifying signed data. The host does not re-sign or validate DNSSEC.
* DROP leaves TCP open for subsequent queries, subject to the normal timeout.
* ALLOW does not change domain policy, upstream selection or transport checks.
* All v1 lifetime/threading rules apply; result is writable only during the
* callback and must not be retained. Web hooks retain v1 return semantics.
*/
struct mudfish_dns_result {
uint32_t action;
uint32_t ttl; /* ANSWER: seconds, zero is allowed. */
uint32_t address_family; /* ANSWER: MUDFISH_DNS_IPV4 or MUDFISH_DNS_IPV6. */
uint8_t address[16]; /* Network byte order; IPv4 uses the first 4 bytes. */
/* REPLACE: module-owned wire response (12..65535 bytes, no TCP framing).
* Must remain valid and unchanged until the next callback on this instance
* or destroy; do not return stack memory or an event's borrowed pointer.
* The host copies before unlocking the instance and never frees this span.
*/
struct mudfish_dns_span response;
};

struct mudfish_dns_module_v2 {
void *context;
int32_t (*on_dns_query)(void *, const struct mudfish_dns_event *,
struct mudfish_dns_result *);
int32_t (*on_dns_response)(void *, const struct mudfish_dns_event *,
struct mudfish_dns_result *);
int32_t (*on_web_hello)(void *, const struct mudfish_dns_web_event *);
int32_t (*on_web_data)(void *, const struct mudfish_dns_web_event *);
void (*destroy)(void *);
};

/* Same initialization contract as v1, with ABI_V2 and sizeof(module_v2).
* The host prefers v2 if exported, otherwise loads v1. A failed v2 init is fatal
* and does not fall back to v1. Existing v1 modules need no changes.
*/
int32_t mudfish_dns_module_init_v2(uint32_t abi_version, size_t module_size,
struct mudfish_dns_module_v2 *module);

#ifdef __cplusplus
}
#endif
#endif