Lumaktaw sa pangunahing nilalaman

mudfish_dns_module.h

I-download ang mudfish_dns_module.h at ilagay ito sa parehong direktoryo ng C source ng iyong module. Nasa ibaba ang buong header na ibinibigay ng Mudfish DNS kabilang ang mga deklarasyon sa compatibility. Gamitin ang C ABI v2 para sa mga module sa gabay na ito.

Nasa halimbawa ng policy.c ang build command at mga halimbawa ng aksyon sa DNS. Para sa pag-load ng module, operasyon ng hook, at mga panuntunan sa pagmamay-ari ng buffer, sumangguni sa Mga Native Module.

Mga Type na Ginagamit sa v2 Module​

TypeGamit
mudfish_dns_spanPointer at haba ng hiniram na input o kapalit na tugon na pagmamay-ari ng module. Ang mga string ay hindi nagtatapos sa NUL.
mudfish_dns_eventWire data ng DNS query at tugon, pinagmulan ng tugon, orihinal na destinasyon, at status ng umiiral na patakaran sa domain.
mudfish_dns_web_eventData sa web, Host/SNI, destinasyon, protocol, direksyon, at status ng umiiral na patakaran sa domain. Nananatiling naka-encrypt ang HTTPS data.
mudfish_dns_resultAksyon sa DNS at opsyonal na address ng tugon, TTL, o kapalit na tugon.
mudfish_dns_module_v2Context ng module, mga opsyonal na callback sa DNS at web, at cleanup callback.

I-expose nang panlabas ang mudfish_dns_module_init_v2() gamit ang signature sa ibaba. Nagsisimula ang host kung saan NULL ang lahat ng field ng module. Bago magsulat ng value sa mga field, suriin muna ang bersyon ng ABI at laki ng struct. Iwang NULL ang mga hindi ginagamit na hook at magbalik ng 0 kapag matagumpay.

Kung mabigo sa pag-initialize, direktang linisin ang mga inilaang resource. Kung magtagumpay sa pag-initialize, tatawagin ng host nang isang beses ang destroy() bago i-unload ang library kapag hindi na ginagamit ang module. Ihinto rito ang mga thread na pagmamay-ari ng module at hintaying matapos ang mga ito.

Buong Header​

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