public release
This commit is contained in:
parent
76ffd7af5b
commit
da7f82a6dd
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
/target
|
/target
|
||||||
/result
|
/result
|
||||||
/unbound-mod-test-config
|
unbound-mod-test-config
|
||||||
/unbound-mod-test-data
|
unbound-mod-test-data
|
||||||
|
|
51
Cargo.lock
generated
51
Cargo.lock
generated
|
@ -39,7 +39,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.72",
|
"syn 2.0.74",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -62,6 +62,25 @@ dependencies = [
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "example"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"boxcar",
|
||||||
|
"filetime",
|
||||||
|
"ipnet",
|
||||||
|
"iptrie",
|
||||||
|
"libc",
|
||||||
|
"mnl",
|
||||||
|
"nftnl",
|
||||||
|
"nix",
|
||||||
|
"radix_trie",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"smallvec",
|
||||||
|
"unbound-mod",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.24"
|
version = "0.2.24"
|
||||||
|
@ -273,29 +292,29 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.205"
|
version = "1.0.207"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
|
checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.205"
|
version = "1.0.207"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
|
checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.72",
|
"syn 2.0.74",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.122"
|
version = "1.0.124"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
|
checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -322,9 +341,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.72"
|
version = "2.0.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -347,19 +366,7 @@ dependencies = [
|
||||||
name = "unbound-mod"
|
name = "unbound-mod"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boxcar",
|
|
||||||
"ctor",
|
"ctor",
|
||||||
"filetime",
|
|
||||||
"ipnet",
|
|
||||||
"iptrie",
|
|
||||||
"libc",
|
|
||||||
"mnl",
|
|
||||||
"nftnl",
|
|
||||||
"nix",
|
|
||||||
"radix_trie",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"smallvec",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
45
Cargo.toml
45
Cargo.toml
|
@ -1,42 +1,3 @@
|
||||||
[package]
|
[workspace]
|
||||||
name = "unbound-mod"
|
members = ["example", "unbound-mod"]
|
||||||
version = "0.1.0"
|
resolver = "2"
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["rlib", "cdylib"]
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
boxcar = { version = "0.2.5", optional = true }
|
|
||||||
ctor = { version = "0.2.8", optional = true }
|
|
||||||
filetime = { version = "0.2.24", optional = true }
|
|
||||||
ipnet = { version = "2.9.0", features = ["serde"], optional = true }
|
|
||||||
iptrie = { version = "0.8.5", optional = true }
|
|
||||||
libc = { version = "0.2.155", optional = true }
|
|
||||||
mnl = { version = "0.2.2", features = ["mnl-1-0-4"], optional = true }
|
|
||||||
nftnl = { version = "0.6.2", features = ["nftnl-1-1-2"], optional = true }
|
|
||||||
nix = { version = "0.29.0", features = ["poll", "user"], optional = true }
|
|
||||||
radix_trie = { version = "0.2.1", optional = true }
|
|
||||||
serde = { version = "1.0.205", features = ["derive"], optional = true }
|
|
||||||
serde_json = { version = "1.0.122", optional = true }
|
|
||||||
smallvec = { version = "1.13.2", optional = true }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
example = [
|
|
||||||
"boxcar",
|
|
||||||
"ctor",
|
|
||||||
"filetime",
|
|
||||||
"ipnet",
|
|
||||||
"iptrie",
|
|
||||||
"libc",
|
|
||||||
"mnl",
|
|
||||||
"nftnl",
|
|
||||||
"nix",
|
|
||||||
"radix_trie",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
default = ["example"]
|
|
||||||
|
|
28
LICENSE
Normal file
28
LICENSE
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2024, chayleaf
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
13
README.md
Normal file
13
README.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# unbound-rust-mod
|
||||||
|
|
||||||
|
This is a library for writing Unbound modules in Rust. See
|
||||||
|
[`example`](./example) for an example module.
|
||||||
|
|
||||||
|
Most of Unbound's features don't have safe bindings, so you might have
|
||||||
|
to write some yourself - in that case, PRs are appreciated.
|
||||||
|
|
||||||
|
To regenerate the bindings, there's a small problem - you actually
|
||||||
|
need to run Unbound's configure script for that. That's why I provide a
|
||||||
|
Nix file to generate them (running `nix build .#bindings` in project
|
||||||
|
root will produce the bindings at the `result` symlink). Alternatively,
|
||||||
|
you may call rust-bindgen manually.
|
24
example/Cargo.toml
Normal file
24
example/Cargo.toml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[package]
|
||||||
|
name = "example"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["rlib", "cdylib"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
boxcar = "0.2.5"
|
||||||
|
filetime = "0.2.24"
|
||||||
|
ipnet = { version = "2.9.0", features = ["serde"] }
|
||||||
|
iptrie = "0.8.5"
|
||||||
|
libc = "0.2.155"
|
||||||
|
mnl = { version = "0.2.2", features = ["mnl-1-0-4"] }
|
||||||
|
nftnl = { version = "0.6.2", features = ["nftnl-1-1-2"] }
|
||||||
|
nix = { version = "0.29.0", features = ["poll", "user"] }
|
||||||
|
radix_trie = "0.2.1"
|
||||||
|
serde = { version = "1.0.205", features = ["derive"] }
|
||||||
|
serde_json = "1.0.122"
|
||||||
|
smallvec = "1.13.2"
|
||||||
|
unbound-mod = { path = "../unbound-mod", default-features = false }
|
12
example/README.md
Normal file
12
example/README.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# unbound-rust-mod Example
|
||||||
|
|
||||||
|
This is an example module written using unbound-rust-mod. It
|
||||||
|
automatically populates nft sets using IP and domain info from .json
|
||||||
|
files. On start, it checks various environment variables, then loads
|
||||||
|
the .json files. The IPs are added immediately, but the domains are only
|
||||||
|
added if they're already in the module's cache (stored on the
|
||||||
|
filesystem) or whenever Unbound sends a response. Additionally, it
|
||||||
|
optionally supports live editing certain domain sets by sending a
|
||||||
|
command (that is, a specially formatted DNS request). This could be done
|
||||||
|
using an HTTP server, but that is a holdover from when this was still a
|
||||||
|
Python module (which took 100 seconds to load...)
|
|
@ -109,21 +109,11 @@ mod tests {
|
||||||
assert!(!tree.contains([&"a", &"c"]));
|
assert!(!tree.contains([&"a", &"c"]));
|
||||||
let mut it = tree.iter();
|
let mut it = tree.iter();
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
it.next()
|
it.next().unwrap().copied().collect::<String>().as_str(),
|
||||||
.unwrap()
|
|
||||||
.into_iter()
|
|
||||||
.copied()
|
|
||||||
.collect::<String>()
|
|
||||||
.as_str(),
|
|
||||||
"ab" | "bcd"
|
"ab" | "bcd"
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
it.next()
|
it.next().unwrap().copied().collect::<String>().as_str(),
|
||||||
.unwrap()
|
|
||||||
.into_iter()
|
|
||||||
.copied()
|
|
||||||
.collect::<String>()
|
|
||||||
.as_str(),
|
|
||||||
"ab" | "bcd"
|
"ab" | "bcd"
|
||||||
));
|
));
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::type_complexity)]
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
|
@ -12,7 +13,6 @@ use std::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use ctor::ctor;
|
|
||||||
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
||||||
use iptrie::IpPrefix;
|
use iptrie::IpPrefix;
|
||||||
use serde::{
|
use serde::{
|
||||||
|
@ -21,12 +21,15 @@ use serde::{
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
unbound::{rr_class, rr_type, ModuleEvent, ModuleExtState, ReplyInfo},
|
|
||||||
UnboundMod,
|
|
||||||
};
|
|
||||||
use domain_tree::PrefixSet;
|
use domain_tree::PrefixSet;
|
||||||
use nftables::{nftables_thread, NftData};
|
use nftables::{nftables_thread, NftData};
|
||||||
|
use unbound_mod::{
|
||||||
|
unbound::{
|
||||||
|
rr_class, rr_type, ModuleEnvMut, ModuleEvent, ModuleExtState, ModuleQstateMut,
|
||||||
|
OutboundEntryMut, ReplyInfo,
|
||||||
|
},
|
||||||
|
UnboundMod,
|
||||||
|
};
|
||||||
|
|
||||||
mod domain_tree;
|
mod domain_tree;
|
||||||
mod nftables;
|
mod nftables;
|
||||||
|
@ -34,10 +37,7 @@ mod nftables;
|
||||||
type Domain = SmallVec<[u8; 32]>;
|
type Domain = SmallVec<[u8; 32]>;
|
||||||
type DomainSeg = SmallVec<[u8; 16]>;
|
type DomainSeg = SmallVec<[u8; 16]>;
|
||||||
|
|
||||||
#[ctor]
|
unbound_mod::set_module!(ExampleMod);
|
||||||
fn setup() {
|
|
||||||
crate::set_unbound_mod::<ExampleMod>();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct IpNetDeser(IpNet);
|
struct IpNetDeser(IpNet);
|
||||||
struct IpNetVisitor;
|
struct IpNetVisitor;
|
||||||
|
@ -708,15 +708,15 @@ impl UnboundMod for ExampleMod {
|
||||||
type EnvData = ();
|
type EnvData = ();
|
||||||
type QstateData = ();
|
type QstateData = ();
|
||||||
|
|
||||||
fn init(_env: &mut crate::unbound::ModuleEnvMut<Self::EnvData>) -> Result<Self, ()> {
|
fn init(_env: &mut ModuleEnvMut<Self::EnvData>) -> Result<Self, ()> {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
&self,
|
&self,
|
||||||
qstate: &mut crate::unbound::ModuleQstateMut<Self::QstateData>,
|
qstate: &mut ModuleQstateMut<Self::QstateData>,
|
||||||
event: ModuleEvent,
|
event: ModuleEvent,
|
||||||
_entry: Option<&mut crate::unbound::OutboundEntryMut>,
|
_entry: Option<&mut OutboundEntryMut>,
|
||||||
) -> Option<ModuleExtState> {
|
) -> Option<ModuleExtState> {
|
||||||
match event {
|
match event {
|
||||||
ModuleEvent::New | ModuleEvent::Pass => {
|
ModuleEvent::New | ModuleEvent::Pass => {
|
||||||
|
@ -755,10 +755,8 @@ mod test {
|
||||||
use ipnet::IpNet;
|
use ipnet::IpNet;
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
use crate::{
|
use super::{ignore, ExampleMod, IpCacheKey, IpNetDeser, DATA_PREFIX};
|
||||||
example::{ignore, ExampleMod, IpCacheKey, IpNetDeser, DATA_PREFIX},
|
use unbound_mod::unbound::ModuleExtState;
|
||||||
unbound::ModuleExtState,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
|
@ -9,7 +9,7 @@ use std::{
|
||||||
sync::mpsc,
|
sync::mpsc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::example::{Helper, DATA_PREFIX};
|
use crate::{Helper, DATA_PREFIX};
|
||||||
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
||||||
use iptrie::RTrieSet;
|
use iptrie::RTrieSet;
|
||||||
use mnl::mnl_sys;
|
use mnl::mnl_sys;
|
14
flake.nix
14
flake.nix
|
@ -19,7 +19,12 @@
|
||||||
outputs = [ "out" ];
|
outputs = [ "out" ];
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
cp ${./dummy.h} ./dummy.h
|
cp ${./dummy.h} ./dummy.h
|
||||||
bindgen ./dummy.h -- -I $PWD > $out
|
opts=()
|
||||||
|
for file in **/*.h; do
|
||||||
|
opts+=(--allowlist-file "$PWD/$file")
|
||||||
|
done
|
||||||
|
|
||||||
|
bindgen --no-layout-tests "''${opts[@]}" dummy.h -- -I "$PWD" > "$out"
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
unbound-mod = let
|
unbound-mod = let
|
||||||
|
@ -28,13 +33,18 @@
|
||||||
in craneLib.buildPackage {
|
in craneLib.buildPackage {
|
||||||
pname = "unbound-mod";
|
pname = "unbound-mod";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
|
cargoExtraArgs = "--package example";
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
cp ${bindings} src/bindings.rs
|
ls -la
|
||||||
|
cp ${bindings} unbound-mod/src/bindings.rs
|
||||||
'';
|
'';
|
||||||
src = nixpkgs.lib.cleanSourceWith {
|
src = nixpkgs.lib.cleanSourceWith {
|
||||||
src = ./.;
|
src = ./.;
|
||||||
filter = path: type: lib.hasSuffix ".h" path || craneLib.filterCargoSources path type;
|
filter = path: type: lib.hasSuffix ".h" path || craneLib.filterCargoSources path type;
|
||||||
};
|
};
|
||||||
|
postInstall = ''
|
||||||
|
mv $out/lib/libexample.so $out/lib/libunbound_mod.so
|
||||||
|
'';
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
LIBMNL_LIB_DIR = "${nixpkgs.lib.getLib pkgs.libmnl}/lib";
|
LIBMNL_LIB_DIR = "${nixpkgs.lib.getLib pkgs.libmnl}/lib";
|
||||||
LIBNFTNL_LIB_DIR = "${nixpkgs.lib.getLib pkgs.libnftnl}/lib";
|
LIBNFTNL_LIB_DIR = "${nixpkgs.lib.getLib pkgs.libnftnl}/lib";
|
||||||
|
|
22040
src/bindings.rs
22040
src/bindings.rs
File diff suppressed because it is too large
Load diff
9
unbound-mod/Cargo.toml
Normal file
9
unbound-mod/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "unbound-mod"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ctor = "0.2.8"
|
2110
unbound-mod/src/bindings.rs
Normal file
2110
unbound-mod/src/bindings.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity, clippy::missing_safety_doc)]
|
||||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||||
|
|
||||||
use unbound::ModuleExtState;
|
use unbound::ModuleExtState;
|
||||||
|
@ -13,12 +13,27 @@ use unbound::ModuleExtState;
|
||||||
clippy::nursery,
|
clippy::nursery,
|
||||||
clippy::pedantic
|
clippy::pedantic
|
||||||
)]
|
)]
|
||||||
mod bindings;
|
#[doc(hidden)]
|
||||||
|
pub mod bindings;
|
||||||
mod combine;
|
mod combine;
|
||||||
#[cfg(feature = "example")]
|
|
||||||
mod example;
|
|
||||||
mod exports;
|
mod exports;
|
||||||
mod unbound;
|
pub mod unbound;
|
||||||
|
|
||||||
|
pub use bindings as sys;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use ctor;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! set_module {
|
||||||
|
($mod:ty) => {
|
||||||
|
use unbound_mod::ctor::ctor;
|
||||||
|
#[ctor]
|
||||||
|
fn _internal_module_setup() {
|
||||||
|
unbound_mod::set_unbound_mod::<$mod>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub trait UnboundMod: Send + Sync + Sized + RefUnwindSafe + UnwindSafe {
|
pub trait UnboundMod: Send + Sync + Sized + RefUnwindSafe + UnwindSafe {
|
||||||
type EnvData;
|
type EnvData;
|
|
@ -448,32 +448,32 @@ type RrsetIdType = rrset_id_type;
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub enum ModuleEvent {
|
pub enum ModuleEvent {
|
||||||
/// new query
|
/// new query
|
||||||
New = 0,
|
New = bindings::module_ev_module_event_new,
|
||||||
/// query passed by other module
|
/// query passed by other module
|
||||||
Pass = 1,
|
Pass = bindings::module_ev_module_event_pass,
|
||||||
/// reply inbound from server
|
/// reply inbound from server
|
||||||
Reply = 2,
|
Reply = bindings::module_ev_module_event_reply,
|
||||||
/// no reply, timeout or other error
|
/// no reply, timeout or other error
|
||||||
NoReply = 3,
|
NoReply = bindings::module_ev_module_event_noreply,
|
||||||
/// reply is there, but capitalisation check failed
|
/// reply is there, but capitalisation check failed
|
||||||
CapsFail = 4,
|
CapsFail = bindings::module_ev_module_event_capsfail,
|
||||||
/// next module is done, and its reply is awaiting you
|
/// next module is done, and its reply is awaiting you
|
||||||
ModDone = 5,
|
ModDone = bindings::module_ev_module_event_moddone,
|
||||||
/// error
|
/// error
|
||||||
Error = 6,
|
Error = bindings::module_ev_module_event_error,
|
||||||
Unknown = 7,
|
Unknown = 99,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<module_ev> for ModuleEvent {
|
impl From<module_ev> for ModuleEvent {
|
||||||
fn from(value: module_ev) -> Self {
|
fn from(value: module_ev) -> Self {
|
||||||
match value {
|
match value {
|
||||||
0 => Self::New,
|
bindings::module_ev_module_event_new => Self::New,
|
||||||
1 => Self::Pass,
|
bindings::module_ev_module_event_pass => Self::Pass,
|
||||||
2 => Self::Reply,
|
bindings::module_ev_module_event_reply => Self::Reply,
|
||||||
3 => Self::NoReply,
|
bindings::module_ev_module_event_noreply => Self::NoReply,
|
||||||
4 => Self::CapsFail,
|
bindings::module_ev_module_event_capsfail => Self::CapsFail,
|
||||||
5 => Self::ModDone,
|
bindings::module_ev_module_event_moddone => Self::ModDone,
|
||||||
6 => Self::Error,
|
bindings::module_ev_module_event_error => Self::Error,
|
||||||
_ => Self::Unknown,
|
_ => Self::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue