mudfish_dns_module.h
ดาวน์โหลด mudfish_dns_module.h แล้ววางในไดเรกทอรีเดียวกับซอร์ส C ของโมดูล ด้านล่างเป็นเฮดเดอร์ทั้งหมดที่ Mudfish DNS จัดเตรียมไว้ รวมการประกาศเพื่อความเข้ากันได้ ใช้ C ABI v2 สำหรับโมดูลในคู่มือนี้
ตัวอย่าง policy.c มีคำสั่งบิลด์และตัวอย่างการทำงานของ DNS สำหรับการโหลดโมดูล การทำงานของฮุก และกฎความเป็นเจ้าของบัฟเฟอร์ โปรดดู โมดูลเนทีฟ
ชนิดข้อมูลที่ใช้ในโมดูล v2
| ชนิดข้อมูล | หน้าที่ |
|---|---|
mudfish_dns_span | ตัวชี้และความยาวของอินพุตที่ยืมมา หรือคำตอบทดแทนที่โมดูลเป็นเจ้าของ สตริงไม่ได้ลงท้ายด้วย NUL |
mudfish_dns_event | ข้อมูลคำถามและคำตอบ DNS ในรูปแบบ wire แหล่งที่มาของคำตอบ ปลายทางเดิม และสถานะนโยบายโดเมนเดิม |
mudfish_dns_web_event | ข้อมูลเว็บ Host/SNI ปลายทาง โปรโตคอล ทิศทาง และสถานะนโยบายโดเมนเดิม ข้อมูล HTTPS ยังคงเข้ารหัสอยู่ |
mudfish_dns_result | การทำงานของ DNS และที่อยู่คำตอบ TTL หรือคำตอบทดแทนที่ระบุเพิ่มเติมได้ |
mudfish_dns_module_v2 | บริบทโมดูล callback ของ DNS และเว็บที่เลือกใช้ได้ และ callback สำหรับปล่อยทรัพยากร |
ส่งออก mudfish_dns_module_init_v2() ด้วยรูปแบบฟังก์ชันด้านล่าง โฮสต์เริ่มต้นโดยกำหนดทุกฟิลด์ของโมดูลเป็น NULL ตรวจสอบเวอร์ชัน ABI และขนาดโครงสร้างก่อนเขียนค่าในฟิลด์ คงฮุกที่ไม่ใช้ไว้เป็น NULL และคืนค่า 0 เมื่อสำเร็จ
หากเริ่มต้นล้มเหลว ให้ปล่อยทรัพยากรที่จัดสรรไว้ด้วยตนเอง หากเริ่มต้นสำเร็จ เมื่อไม่ใช้โมดูลแล้ว โฮสต์จะเรียก destroy() หนึ่งครั้งก่อนนำไลบรารีออกจากหน่วยความจำ ให้หยุดเธรดที่โมดูลเป็นเจ้าของและรอให้สิ้นสุดในขั้นตอนนี้
เฮดเดอร์ทั้งหมด
#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