Skip to main content

Native modules (developers)

Normal use does not require modules. This guide is for developers and administrators extending the Windows or Linux service with native libraries. Modules run inside the service with its privileges, so install only trusted code and keep module files, dependencies, and configuration administrator-owned.

Load a module​

The service reads *.conf files from a modules.d directory beside its config file. Default locations are:

PlatformModule configurationLibrary type
Linux/etc/mudfish-dns/modules.d/.so
Windows%ProgramData%\Mudfish DNS\modules.d\.dll

Each file contains one absolute library path per line. For example, /etc/mudfish-dns/modules.d/10-policy.conf could contain:

/usr/lib/mudfish-dns/modules/policy.so

Files are read in filename order, then line order. Blank lines and lines starting with # are ignored. Do not quote paths or use environment variables or inline comments: those are not expanded. On Windows, write the full absolute path inside the file, including for paths with spaces.

Restart the service after adding, changing, or removing a module. On Linux:

sudo systemctl restart mudfish-dns.service

On Windows, restart the Mudfish DNS service from Services. The app's Start DNS, Stop DNS, and Apply settings actions do not reload modules. An unreadable configuration, invalid path, or load/initialization error prevents the service from starting. An absent or empty module directory is allowed.

For development, repeated --module arguments specify libraries in call order and replace automatic modules.d loading. --config FILE changes the adjacent module directory. --restore-dns performs recovery without loading modules.

Implement hooks​

Read the mudfish_dns_module.h header or download mudfish_dns_module.h. It defines the structures, hooks, actions, and lifetime rules used by modules. This guide uses C ABI v2. Export mudfish_dns_module_init_v2() and check MUDFISH_DNS_MODULE_ABI_V2 and the supplied structure size before filling in hooks. Return zero on successful initialization.

HookCalled when
on_dns_queryA parsed query is accepted, before cache lookup or forwarding.
on_dns_responseA response is selected, before caching or returning it to the client. Cached responses also pass through this hook.
on_web_helloInitial HTTP Host/TLS SNI inspection finishes, before connecting or processing the initial data.
on_web_dataSubsequent client data or server data is read, before forwarding it.

DNS actions​

For v2 DNS hooks, return 0 for success and set result->action:

ActionEffect
MUDFISH_DNS_CONTINUEContinue to the next module and normal processing.
MUDFISH_DNS_ALLOWEnd the current hook chain and continue normal resolution or return the selected response.
MUDFISH_DNS_BLOCKReturn REFUSED.
MUDFISH_DNS_DROPDiscard without sending a DNS response.
MUDFISH_DNS_ANSWERSynthesize an answer using the supplied IPv4/IPv6 address and TTL.
MUDFISH_DNS_REPLACEUse a complete DNS wire response supplied by the module.

Do not return the action directly from a v2 DNS hook. A nonzero function return or invalid result produces SERVFAIL. ALLOW ends only the current hook chain; it does not bypass domain rules, transport permissions, or certificate checks. Query results other than DROP still pass through the response hooks.

Web hooks return MUDFISH_DNS_CONTINUE or MUDFISH_DNS_REJECT directly. Web rejection closes the connection. Web hooks require enabled web protection and do not expose decrypted HTTPS content.

Buffers, threading, and caching​

Input events and buffers are read-only and valid only during the callback. A replacement response must use module-owned memory valid until that module's next callback or destruction; do not return stack memory or a borrowed event pointer. Its DNS ID, opcode, and question must match the original query. Callbacks for one instance are serialized but can run on different threads; keep them short and do not unwind across the ABI.

Synthetic, replaced, blocked, or dropped results are not stored in the host cache. Replacing a cached response does not alter the original cached entry. The host clears the AD flag on replacement responses and does not validate or re-sign DNSSEC; modules modifying signed data must handle invalidated signatures.

Example and header​

The following pages include the complete example source and required header. You do not need a checkout of the Mudfish DNS source tree.

FileContents
policy.c — DNS policy exampleAllow, block, or drop DNS queries; synthesize an IP answer; rewrite an answer's address and TTL. Includes Linux build and test commands.
mudfish_dns_module.h — module headerABI declarations, hook signatures, action constants, and buffer ownership rules.

Download policy.c and mudfish_dns_module.h into the same directory before building. The example's build command produces a Linux .so library.