From ce42b61e58c3682b14dfb6c1f5a74a1b7380061e Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 31 Jan 2025 17:22:41 +0100 Subject: [PATCH] Modularize: split out misc.rs for general stuff --- pdns/recursordist/rec-main.cc | 7 - pdns/recursordist/rec-web-stubs.hh | 3 + pdns/recursordist/settings/cxxsupport.cc | 44 ++-- pdns/recursordist/settings/rust-bridge-in.rs | 9 +- .../recursordist/settings/rust-preamble-in.rs | 2 + pdns/recursordist/settings/rust/.gitignore | 1 + pdns/recursordist/settings/rust/Cargo.lock | 1 - pdns/recursordist/settings/rust/Cargo.toml | 3 +- pdns/recursordist/settings/rust/Makefile.am | 16 +- pdns/recursordist/settings/rust/build.rs | 6 +- .../recursordist/settings/rust/build_settings | 3 +- pdns/recursordist/settings/rust/src/bridge.hh | 44 ++-- pdns/recursordist/settings/rust/src/bridge.rs | 7 +- pdns/recursordist/settings/rust/src/misc.rs | 47 +++++ pdns/recursordist/settings/rust/src/web.rs | 198 ++++++++---------- pdns/recursordist/ws-recursor.cc | 11 +- pdns/recursordist/ws-recursor.hh | 12 +- pdns/webserver.hh | 2 + 18 files changed, 233 insertions(+), 183 deletions(-) create mode 100644 pdns/recursordist/settings/rust/src/misc.rs diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index b258792664d2..9e3ebb976569 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -274,8 +274,6 @@ int RecThreadInfo::runThreads(Logr::log_t log) } if (::arg().mustDo("webserver")) { - extern void serveRustWeb(); - cerr << "CALL serveRustWeb" << endl; serveRustWeb(); } @@ -358,13 +356,8 @@ int RecThreadInfo::runThreads(Logr::log_t log) info.start(currentThreadId, "web+stat", cpusMap, log); if (::arg().mustDo("webserver")) { - extern void serveRustWeb(); - cerr << "WS is CALLED " << endl; serveRustWeb(); } - else { - cerr << "WS is FALSE " << endl; - } for (auto& tInfo : RecThreadInfo::infos()) { tInfo.thread.join(); if (tInfo.exitCode != 0) { diff --git a/pdns/recursordist/rec-web-stubs.hh b/pdns/recursordist/rec-web-stubs.hh index 316d84dbabc8..60a2d3938bfc 100644 --- a/pdns/recursordist/rec-web-stubs.hh +++ b/pdns/recursordist/rec-web-stubs.hh @@ -4,6 +4,9 @@ namespace pdns::rust::web::rec #define WRAPPER(A) \ void A(const Request& /* unused */, Response& /* unused */) {} +class Request; +class Response; + WRAPPER(apiDiscovery) WRAPPER(apiDiscoveryV1) WRAPPER(apiServer) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index ec94e9121c8c..e41ba09db502 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -42,6 +42,7 @@ #include "iputils.hh" #include "bridge.hh" #include "settings/rust/web.rs.h" +#include "settings/rust/misc.rs.h" ::rust::Vec<::rust::String> pdns::settings::rec::getStrings(const std::string& name) { @@ -1441,24 +1442,7 @@ pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::tryReadYAML(const s return yamlstatus; } -uint16_t pdns::rust::settings::rec::qTypeStringToCode(::rust::Str str) -{ - std::string tmp(str.data(), str.length()); - return QType::chartocode(tmp.c_str()); -} - -bool pdns::rust::settings::rec::isValidHostname(::rust::Str str) -{ - try { - auto name = DNSName(string(str)); - return name.isHostname(); - } - catch (...) { - return false; - } -} - -namespace pdns::rust::web::rec +namespace pdns::rust::misc { template @@ -1478,7 +1462,25 @@ template template class Wrapper<::NetmaskGroup>; template class Wrapper<::ComboAddress>; - //template class Wrapper>; + +uint16_t qTypeStringToCode(::rust::Str str) +{ + std::string tmp(str.data(), str.length()); + return QType::chartocode(tmp.c_str()); +} + +bool isValidHostname(::rust::Str str) +{ + try { + auto name = DNSName(string(str)); + return name.isHostname(); + } + catch (...) { + return false; + } +} + +void findBetterSolution(const std::unique_ptr& /* x */){}; std::unique_ptr comboaddress(::rust::Str str) { @@ -1490,7 +1492,7 @@ bool matches(const std::unique_ptr& nmg, const std::unique_ptrget().match(address->get()); } -void log(const std::shared_ptr& logger, pdns::rust::web::rec::Priority log_level, ::rust::Str msg, const ::rust::Vec& values) + void log(const std::shared_ptr& logger, pdns::rust::misc::Priority log_level, ::rust::Str msg, const ::rust::Vec& values) { auto log = logger; for (const auto& [key, value] : values) { @@ -1499,7 +1501,7 @@ void log(const std::shared_ptr& logger, pdns::rust::web::rec::Priority l log->info(static_cast(log_level), std::string(msg)); } -void error(const std::shared_ptr& logger, pdns::rust::web::rec::Priority log_level, ::rust::Str error, ::rust::Str msg, const ::rust::Vec& values) + void error(const std::shared_ptr& logger, pdns::rust::misc::Priority log_level, ::rust::Str error, ::rust::Str msg, const ::rust::Vec& values) { auto log = logger; for (const auto& [key, value] : values) { diff --git a/pdns/recursordist/settings/rust-bridge-in.rs b/pdns/recursordist/settings/rust-bridge-in.rs index 731cc15a8584..176ebad2ee39 100644 --- a/pdns/recursordist/settings/rust-bridge-in.rs +++ b/pdns/recursordist/settings/rust-bridge-in.rs @@ -310,8 +310,8 @@ pub struct IncomingTLS { certificate: String, #[serde(default, skip_serializing_if = "crate::is_default")] key: String, - #[serde(default, skip_serializing_if = "crate::is_default")] - password: String, + // #[serde(default, skip_serializing_if = "crate::is_default")] + // password: String, Not currently supported, as rusttls does not support this out of the box } #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)] #[serde(deny_unknown_fields)] @@ -410,8 +410,3 @@ extern "Rust" { fn api_delete_zones(file: &str) -> Result<()>; } -unsafe extern "C++" { - include!("bridge.hh"); - fn qTypeStringToCode(name: &str) -> u16; - fn isValidHostname(name: &str) -> bool; -} diff --git a/pdns/recursordist/settings/rust-preamble-in.rs b/pdns/recursordist/settings/rust-preamble-in.rs index ee611f1533ef..d3758f6779cf 100644 --- a/pdns/recursordist/settings/rust-preamble-in.rs +++ b/pdns/recursordist/settings/rust-preamble-in.rs @@ -30,6 +30,8 @@ use helpers::*; mod bridge; use bridge::*; +mod misc; + mod web; // leaving this out causes link issues // Suppresses "Deserialize unused" warning diff --git a/pdns/recursordist/settings/rust/.gitignore b/pdns/recursordist/settings/rust/.gitignore index d31bd391e756..e9e427e1cd87 100644 --- a/pdns/recursordist/settings/rust/.gitignore +++ b/pdns/recursordist/settings/rust/.gitignore @@ -4,5 +4,6 @@ /cxx.h /lib.rs.h /web.rs.h +/misc.rs.h src/lib.rs .dir-locals.el diff --git a/pdns/recursordist/settings/rust/Cargo.lock b/pdns/recursordist/settings/rust/Cargo.lock index 4eca9bc1136e..68014e7988f1 100644 --- a/pdns/recursordist/settings/rust/Cargo.lock +++ b/pdns/recursordist/settings/rust/Cargo.lock @@ -457,7 +457,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", diff --git a/pdns/recursordist/settings/rust/Cargo.toml b/pdns/recursordist/settings/rust/Cargo.toml index c68288d30301..01b5e803427e 100644 --- a/pdns/recursordist/settings/rust/Cargo.toml +++ b/pdns/recursordist/settings/rust/Cargo.toml @@ -22,11 +22,12 @@ hyper-util = { version = "0.1", features = ["tokio"]} bytes = "1.8" form_urlencoded = "1.2" hyper-rustls = { version = "0.27", default-features = false } -rustls = { version = "0.23", default-features = false, features = ["ring"] } +rustls = { version = "0.23", default-features = false, features = [] } rustls-pemfile = "2.2" pki-types = { package = "rustls-pki-types", version = "1.10" } tokio-rustls = { version = "0.26", default-features = false } uuid = { version = "1.12.1", features = ["v4"] } + [build-dependencies] cxx-build = "1.0" diff --git a/pdns/recursordist/settings/rust/Makefile.am b/pdns/recursordist/settings/rust/Makefile.am index 6ade7921d08b..504518913675 100644 --- a/pdns/recursordist/settings/rust/Makefile.am +++ b/pdns/recursordist/settings/rust/Makefile.am @@ -3,20 +3,30 @@ CARGO ?= cargo all install: libsettings.a EXTRA_DIST = \ - Cargo.toml \ Cargo.lock \ + Cargo.toml \ build.rs \ src/bridge.rs \ src/helpers.rs \ + src/misc.rs \ src/web.rs # should actually end up in a target specific dir... -libsettings.a lib.rs.h web.rs.h: src/web.rs src/bridge.rs src/lib.rs src/helpers.rs Cargo.toml Cargo.lock build.rs +libsettings.a lib.rs.h web.rs.h misc.rs.h: \ + Cargo.lock \ + Cargo.toml \ + build.rs \ + src/bridge.rs \ + src/helpers.rs \ + src/lib.rs \ + src/misc.rs \ + src/web.rs SYSCONFDIR=$(sysconfdir) NODCACHEDIRNOD=$(localstatedir)/nod NODCACHEDIRUDR=$(localstatedir)/udr $(CARGO) build --release $(RUST_TARGET) --target-dir=$(builddir)/target --manifest-path ${srcdir}/Cargo.toml cp target/$(RUSTC_TARGET_ARCH)/release/libsettings.a libsettings.a cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/settings/src/lib.rs.h lib.rs.h cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/settings/src/web.rs.h web.rs.h + cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/settings/src/misc.rs.h misc.rs.h cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/rust/cxx.h cxx.h clean-local: - rm -rf libsettings.a src/lib.rs lib.rs.h web.rs.h cxx.h target + rm -rf libsettings.a src/lib.rs lib.rs.h web.rs.h cxx.h misc.rs.h target diff --git a/pdns/recursordist/settings/rust/build.rs b/pdns/recursordist/settings/rust/build.rs index cdf64ab167a5..21eb063a8d1a 100644 --- a/pdns/recursordist/settings/rust/build.rs +++ b/pdns/recursordist/settings/rust/build.rs @@ -1,9 +1,13 @@ fn main() { - let sources = vec!["src/lib.rs", "src/web.rs"]; + let sources = vec!["src/lib.rs", "src/web.rs", "src/misc.rs"]; cxx_build::bridges(sources) // .file("src/source.cc") Code callable from Rust is in ../cxxsupport.cc .flag_if_supported("-std=c++17") .flag("-Isrc") .flag("-I../../..") .compile("settings"); + + // lib.rs is genertated an take carte of by parent Makefile + println!("cargo:rerun-if-changed=src/misc.rs"); + println!("cargo:rerun-if-changed=src/web.rs"); } diff --git a/pdns/recursordist/settings/rust/build_settings b/pdns/recursordist/settings/rust/build_settings index 34c6170de0b7..073479a9da70 100755 --- a/pdns/recursordist/settings/rust/build_settings +++ b/pdns/recursordist/settings/rust/build_settings @@ -6,7 +6,6 @@ $CARGO build --release $RUST_TARGET --target-dir=$builddir/target --manifest-path $srcdir/Cargo.toml - cp -vp target/$RUSTC_TARGET_ARCH/release/libsettings.a $builddir/settings/rust/libsettings.a cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/lib.rs.h $srcdir/lib.rs.h cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/lib.rs.h $builddir/settings/rust/lib.rs.h @@ -14,3 +13,5 @@ cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/rust/cxx.h $srcdir/cxx.h cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/rust/cxx.h $builddir/settings/rust/cxx.h cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/web.rs.h $srcdir/web.rs.h cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/web.rs.h $builddir/settings/rust/web.rs.h +cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/misc.rs.h $srcdir/misc.rs.h +cp -vp target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/misc.rs.h $builddir/settings/rust/misc.rs.h diff --git a/pdns/recursordist/settings/rust/src/bridge.hh b/pdns/recursordist/settings/rust/src/bridge.hh index 4c15177313d4..5afe3ef37ae2 100644 --- a/pdns/recursordist/settings/rust/src/bridge.hh +++ b/pdns/recursordist/settings/rust/src/bridge.hh @@ -26,13 +26,6 @@ #include "rust/cxx.h" #include "credentials.hh" -namespace pdns::rust::settings::rec -{ -uint16_t qTypeStringToCode(::rust::Str str); -bool isValidHostname(::rust::Str str); -void setThreadName(::rust::Str str); -} - class NetmaskGroup; union ComboAddress; namespace Logr @@ -40,15 +33,11 @@ namespace Logr class Logger; } - -namespace pdns::rust::web::rec -{ -using CredentialsHolder = ::CredentialsHolder; -struct KeyValue; -struct Request; -struct Response; -struct IncomingWSConfig; +namespace pdns::rust::misc { enum class Priority : uint8_t; +enum class LogLevel : uint8_t; +using Logger = ::Logr::Logger; +struct KeyValue; template class Wrapper @@ -68,9 +57,27 @@ public: private: std::unique_ptr d_ptr; }; + using NetmaskGroup = Wrapper<::NetmaskGroup>; using ComboAddress = Wrapper<::ComboAddress>; -using Logger = ::Logr::Logger; + +uint16_t qTypeStringToCode(::rust::Str str); +bool isValidHostname(::rust::Str str); +std::unique_ptr comboaddress(::rust::Str str); +bool matches(const std::unique_ptr& nmg, const std::unique_ptr& address); +std::shared_ptr withValue(const std::shared_ptr& logger, ::rust::Str key, ::rust::Str val); +void log(const std::shared_ptr& logger, Priority log_level, ::rust::Str msg, const ::rust::Vec& values); +void error(const std::shared_ptr& logger, Priority log_level, ::rust::Str err, ::rust::Str msg, const ::rust::Vec& values); +} + + +namespace pdns::rust::web::rec +{ +using CredentialsHolder = ::CredentialsHolder; +struct KeyValue; +struct Request; +struct Response; +struct IncomingWSConfig; void apiServer(const Request& rustRequest, Response& rustResponse); void apiDiscovery(const Request& rustRequest, Response& rustResponse); @@ -93,9 +100,4 @@ void apiServerSearchData(const Request& rustRequest, Response& rustResponse); void apiServerZoneDetailGET(const Request& rustRequest, Response& rustResponse); void apiServerZoneDetailPUT(const Request& rustRequest, Response& rustResponse); void apiServerZoneDetailDELETE(const Request& rustRequest, Response& rustResponse); -std::unique_ptr comboaddress(::rust::Str str); -bool matches(const std::unique_ptr& nmg, const std::unique_ptr& address); -std::shared_ptr withValue(const std::shared_ptr& logger, ::rust::Str key, ::rust::Str val); -void log(const std::shared_ptr& logger, Priority log_level, ::rust::Str msg, const ::rust::Vec& values); -void error(const std::shared_ptr& logger, Priority log_level, ::rust::Str err, ::rust::Str msg, const ::rust::Vec& values); } diff --git a/pdns/recursordist/settings/rust/src/bridge.rs b/pdns/recursordist/settings/rust/src/bridge.rs index e67931d464c6..701bdc4f9930 100644 --- a/pdns/recursordist/settings/rust/src/bridge.rs +++ b/pdns/recursordist/settings/rust/src/bridge.rs @@ -31,6 +31,7 @@ use std::sync::Mutex; use crate::helpers::OVERRIDE_TAG; use crate::recsettings::{self, *}; use crate::{Merge, ValidationError}; +use crate::misc::rustmisc; impl Default for ForwardZone { fn default() -> Self { @@ -123,9 +124,9 @@ fn is_port_number(str: &str) -> bool { pub fn validate_socket_address_or_name(field: &str, val: &String) -> Result<(), ValidationError> { let sa = validate_socket_address(field, val); - if sa.is_err() && !isValidHostname(val) { + if sa.is_err() && !rustmisc::isValidHostname(val) { let parts: Vec<&str> = val.split(':').collect(); - if parts.len() != 2 || !isValidHostname(parts[0]) || !is_port_number(parts[1]) { + if parts.len() != 2 || !rustmisc::isValidHostname(parts[0]) || !is_port_number(parts[1]) { let msg = format!( "{}: value `{}' is not an IP, IP:port, name or name:port combination", field, val @@ -137,7 +138,7 @@ pub fn validate_socket_address_or_name(field: &str, val: &String) -> Result<(), } fn validate_qtype(field: &str, val: &String) -> Result<(), ValidationError> { - let code = qTypeStringToCode(val); + let code = rustmisc::qTypeStringToCode(val); if code == 0 { let msg = format!("{}: value `{}' is not a qtype", field, val); return Err(ValidationError { msg }); diff --git a/pdns/recursordist/settings/rust/src/misc.rs b/pdns/recursordist/settings/rust/src/misc.rs new file mode 100644 index 000000000000..87118cbf9399 --- /dev/null +++ b/pdns/recursordist/settings/rust/src/misc.rs @@ -0,0 +1,47 @@ +#[cxx::bridge(namespace = "pdns::rust::misc")] +pub mod rustmisc { + + pub enum LogLevel { + None, + Normal, + Detailed, + } + enum Priority { + Absent = 0, + Alert = 1, + Critical = 2, + Error = 3, + Warning = 4, + Notice = 5, + Info = 6, + Debug = 7, + } + struct KeyValue { + key: String, + value: String, + } + + extern "C++" { + type NetmaskGroup; + type ComboAddress; + type Logger; + } + + unsafe extern "C++" { + include!("bridge.hh"); + fn qTypeStringToCode(name: &str) -> u16; + fn isValidHostname(name: &str) -> bool; + fn comboaddress(address: &str) -> UniquePtr; + fn matches(nmg: &UniquePtr, address: &UniquePtr) -> bool; // match is a keyword + fn withValue(logger: &SharedPtr, key: &str, val: &str) -> SharedPtr; + fn log(logger: &SharedPtr, prio: Priority, msg: &str, values: &Vec); + fn error( + logger: &SharedPtr, + prio: Priority, + err: &str, + msg: &str, + values: &Vec, + ); + } +} + diff --git a/pdns/recursordist/settings/rust/src/web.rs b/pdns/recursordist/settings/rust/src/web.rs index b848166c7b18..fa95835a54bb 100644 --- a/pdns/recursordist/settings/rust/src/web.rs +++ b/pdns/recursordist/settings/rust/src/web.rs @@ -28,6 +28,8 @@ use tokio::net::TcpListener; use tokio::runtime::Builder; use tokio::task::JoinSet; +use crate::misc::rustmisc; + type GenericError = Box; type MyResult = std::result::Result; type BoxBody = http_body_util::combinators::BoxBody; @@ -88,11 +90,11 @@ fn nonapi_wrapper( ) { let auth_ok = compare_authorization(ctx, reqheaders); if !auth_ok { - rustweb::log( + rustmisc::log( request.logger, rustweb::Priority::Debug, "Authentication failed", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "urlpath".to_string(), value: request.uri.to_owned(), }], @@ -122,11 +124,11 @@ fn file_wrapper( ) { let auth_ok = compare_authorization(ctx, reqheaders); if !auth_ok { - rustweb::log( + rustmisc::log( request.logger, rustweb::Priority::Debug, "Authentication failed", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "urlpath".to_string(), value: request.uri.to_owned(), }], @@ -153,11 +155,11 @@ fn api_wrapper( header::HeaderValue::from_static("*"), ); if ctx.api_ch.is_null() { - rustweb::log( + rustmisc::log( logger, rustweb::Priority::Error, "Authentication failed, API Key missing in config", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "urlpath".to_string(), value: request.uri.to_owned(), }], @@ -185,11 +187,11 @@ fn api_wrapper( if !auth_ok && allow_password { auth_ok = compare_authorization(ctx, reqheaders); if !auth_ok { - rustweb::log( + rustmisc::log( logger, rustweb::Priority::Debug, "Authentication failed", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "urlpath".to_string(), value: request.uri.to_owned(), }], @@ -199,11 +201,11 @@ fn api_wrapper( } } if !auth_ok { - rustweb::log( + rustmisc::log( logger, rustweb::Priority::Error, "Authentication failed", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "urlpath".to_string(), value: request.uri.to_owned(), }], @@ -250,9 +252,9 @@ struct Context { urls: Vec, password_ch: cxx::UniquePtr, api_ch: cxx::UniquePtr, - acl: cxx::UniquePtr, - logger: cxx::SharedPtr, - loglevel: rustweb::LogLevel, + acl: cxx::UniquePtr, + logger: cxx::SharedPtr, + loglevel: rustmisc::LogLevel, } // Serve a file @@ -272,16 +274,16 @@ fn file( .iter() .position(|x| String::from("/") + x == uripath); if pos.is_none() { - rustweb::log( + rustmisc::log( request.logger, rustweb::Priority::Debug, "not found", &vec![ - rustweb::KeyValue { + rustmisc::KeyValue { key: "method".to_string(), value: method.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "uripath".to_string(), value: uripath.to_string(), }, @@ -294,16 +296,16 @@ fn file( // Return 404 not found response. response.status = StatusCode::NOT_FOUND.as_u16(); response.body = NOTFOUND.to_vec(); - rustweb::log( + rustmisc::log( request.logger, rustweb::Priority::Debug, "not found case 2", &vec![ - rustweb::KeyValue { + rustmisc::KeyValue { key: "method".to_string(), value: method.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "uripath".to_string(), value: uripath.to_string(), }, @@ -407,7 +409,7 @@ fn matcher( fn collect_options( path: &str, response: &mut rustweb::Response, - my_logger: &cxx::SharedPtr, + my_logger: &cxx::SharedPtr, ) { let mut methods = vec![]; for method in [Method::GET, Method::POST, Method::PUT, Method::DELETE] { @@ -465,17 +467,17 @@ fn collect_options( }); } -fn log_request(loglevel: rustweb::LogLevel, request: &rustweb::Request, remote: SocketAddr) { - if loglevel != rustweb::LogLevel::Detailed { +fn log_request(loglevel: rustmisc::LogLevel, request: &rustweb::Request, remote: SocketAddr) { + if loglevel != rustmisc::LogLevel::Detailed { return; } let body = std::str::from_utf8(&request.body).unwrap_or("error: body is not utf8"); let mut vec = vec![ - rustweb::KeyValue { + rustmisc::KeyValue { key: "remote".to_string(), value: remote.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "body".to_string(), value: body.to_string(), }, @@ -490,34 +492,34 @@ fn log_request(loglevel: rustweb::LogLevel, request: &rustweb::Request, remote: let snippet = var.key.to_owned() + "=" + &var.value; str.push_str(&snippet); } - vec.push(rustweb::KeyValue { + vec.push(rustmisc::KeyValue { key: "getVars".to_string(), value: str.to_string(), }); - rustweb::log( + rustmisc::log( request.logger, - rustweb::Priority::Info, + rustmisc::Priority::Info, "Request details", &vec, ); } fn log_response( - loglevel: rustweb::LogLevel, - logger: &cxx::SharedPtr, + loglevel: rustmisc::LogLevel, + logger: &cxx::SharedPtr, response: &rustweb::Response, remote: SocketAddr, ) { - if loglevel != rustweb::LogLevel::Detailed { + if loglevel != rustmisc::LogLevel::Detailed { return; } let body = std::str::from_utf8(&response.body).unwrap_or("error: body is not utf8"); let mut vec = vec![ - rustweb::KeyValue { + rustmisc::KeyValue { key: "remote".to_string(), value: remote.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "body".to_string(), value: body.to_string(), }, @@ -532,11 +534,11 @@ fn log_response( let snippet = var.key.to_owned() + "=" + &var.value; str.push_str(&snippet); } - vec.push(rustweb::KeyValue { + vec.push(rustmisc::KeyValue { key: "headers".to_string(), value: str.to_string(), }); - rustweb::log(logger, rustweb::Priority::Info, "Response details", &vec); + rustmisc::log(logger, rustmisc::Priority::Info, "Response details", &vec); } // Main entry point after a request arrived @@ -546,7 +548,7 @@ async fn process_request( remote: SocketAddr, ) -> MyResult> { let unique = uuid::Uuid::new_v4(); - let my_logger = rustweb::withValue(&ctx.logger, "uniqueid", &unique.to_string()); + let my_logger = rustmisc::withValue(&ctx.logger, "uniqueid", &unique.to_string()); // Convert query part of URI into vars table let mut vars: Vec = vec![]; @@ -677,34 +679,34 @@ async fn process_request( header::CONNECTION, header::HeaderValue::from_str("close").unwrap(), ); - if ctx.loglevel != rustweb::LogLevel::None { + if ctx.loglevel != rustmisc::LogLevel::None { let version = format!("{:?}", version); - rustweb::log( + rustmisc::log( &my_logger, rustweb::Priority::Notice, "Request", &vec![ - rustweb::KeyValue { + rustmisc::KeyValue { key: "remote".to_string(), value: remote.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "method".to_string(), value: method.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "urlpath".to_string(), value: path.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "HTTPVersion".to_string(), value: version, }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "status".to_string(), value: response.status.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "respsize".to_string(), value: len.to_string(), }, @@ -738,13 +740,13 @@ async fn serveweb_async( match stream.peer_addr() { Ok(addr) => { address = addr; - let combo = rustweb::comboaddress(&address.to_string()); - if !rustweb::matches(&ctx.acl, &combo) { - rustweb::log( + let combo = rustmisc::comboaddress(&address.to_string()); + if !rustmisc::matches(&ctx.acl, &combo) { + rustmisc::log( &ctx.logger, rustweb::Priority::Debug, "No ACL match", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "address".to_string(), value: address.to_string(), }], @@ -753,7 +755,7 @@ async fn serveweb_async( } } Err(err) => { - rustweb::error( + rustmisc::error( &ctx.logger, rustweb::Priority::Error, &err.to_string(), @@ -769,7 +771,7 @@ async fn serveweb_async( let tls_stream = match tls_acceptor.accept(stream).await { Ok(tls_stream) => tls_stream, Err(err) => { - rustweb::error( + rustmisc::error( &ctx.logger, rustweb::Priority::Notice, &err.to_string(), @@ -780,7 +782,7 @@ async fn serveweb_async( } }; let io = TokioIo::new(tls_stream); - let my_logger = rustweb::withValue(&ctx.logger, "tls", "true"); + let my_logger = rustmisc::withValue(&ctx.logger, "tls", "true"); let fut = http1::Builder::new().serve_connection( io, service_fn(move |req| { @@ -793,7 +795,7 @@ async fn serveweb_async( tokio::task::spawn(async move { // Finally, we bind the incoming connection to our `process_request` service if let Err(err) = fut.await { - rustweb::error( + rustmisc::error( &my_logger, rustweb::Priority::Notice, &err.to_string(), @@ -813,13 +815,13 @@ async fn serveweb_async( match stream.peer_addr() { Ok(addr) => { address = addr; - let combo = rustweb::comboaddress(&address.to_string()); - if !rustweb::matches(&ctx.acl, &combo) { - rustweb::log( + let combo = rustmisc::comboaddress(&address.to_string()); + if !rustmisc::matches(&ctx.acl, &combo) { + rustmisc::log( &ctx.logger, rustweb::Priority::Debug, "No ACL match", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "address".to_string(), value: address.to_string(), }], @@ -828,9 +830,9 @@ async fn serveweb_async( } } Err(err) => { - rustweb::error( + rustmisc::error( &ctx.logger, - rustweb::Priority::Error, + rustmisc::Priority::Error, &err.to_string(), "Can't get peer address", &vec![], @@ -839,7 +841,7 @@ async fn serveweb_async( } } let io = TokioIo::new(stream); - let my_logger = rustweb::withValue(&ctx.logger, "tls", "false"); + let my_logger = rustmisc::withValue(&ctx.logger, "tls", "false"); let fut = http1::Builder::new().serve_connection( io, service_fn(move |req| { @@ -852,9 +854,9 @@ async fn serveweb_async( tokio::task::spawn(async move { // Finally, we bind the incoming connection to our `process_request` service if let Err(err) = fut.await { - rustweb::error( + rustmisc::error( &my_logger, - rustweb::Priority::Notice, + rustmisc::Priority::Notice, &err.to_string(), "Error serving web connection", &vec![], @@ -870,9 +872,9 @@ pub fn serveweb( urls: &[String], password_ch: cxx::UniquePtr, api_ch: cxx::UniquePtr, - acl: cxx::UniquePtr, - logger: cxx::SharedPtr, - loglevel: rustweb::LogLevel, + acl: cxx::UniquePtr, + logger: cxx::SharedPtr, + loglevel: rustmisc::LogLevel, ) -> Result<(), std::io::Error> { // Context, atomically reference counted let ctx = Arc::new(Context { @@ -895,7 +897,7 @@ pub fn serveweb( // waits (forever) for all of them to complete by joining them all. let mut set = JoinSet::new(); for config in incoming { - rustweb::log(&ctx.logger, rustweb::Priority::Warning, "Config", &vec![]); + rustmisc::log(&ctx.logger, rustweb::Priority::Warning, "Config", &vec![]); for addr_str in &config.addresses { let addr = match SocketAddr::from_str(addr_str) { Ok(val) => val, @@ -913,21 +915,21 @@ pub fn serveweb( let tls = crate::web::rustweb::IncomingTLS { certificate: config.tls.certificate.clone(), key: config.tls.key.clone(), - password: config.tls.password.clone(), + // password: config.tls.password.clone(), not supported (yet), ruttls does not handle it }; if !tls.certificate.is_empty() { tls_enabled = true; } - rustweb::log( + rustmisc::log( &ctx.logger, rustweb::Priority::Info, "web service listening", &vec![ - rustweb::KeyValue { + rustmisc::KeyValue { key: "address".to_string(), value: addr.to_string(), }, - rustweb::KeyValue { + rustmisc::KeyValue { key: "tls".to_string(), value: tls_enabled.to_string(), }, @@ -937,12 +939,12 @@ pub fn serveweb( } Err(err) => { let msg = format!("Unable to bind web socket: {}", err); - rustweb::error( + rustmisc::error( &ctx.logger, rustweb::Priority::Error, &err.to_string(), "Unable to bind to web socket", - &vec![rustweb::KeyValue { + &vec![rustmisc::KeyValue { key: "address".to_string(), value: addr.to_string(), }], @@ -958,9 +960,9 @@ pub fn serveweb( runtime.block_on(async { while let Some(res) = set.join_next().await { let msg = format!("{:?}", res); - rustweb::error( + rustmisc::error( &ctx.logger, - rustweb::Priority::Error, + rustmisc::Priority::Error, &msg, "rustweb thread exited", &vec![], @@ -1004,24 +1006,31 @@ fn load_private_key(filename: &str) -> std::io::Result, } - enum Priority { - Absent = 0, - Alert = 1, - Critical = 2, - Error = 3, - Warning = 4, - Notice = 5, - Info = 6, - Debug = 7, - } - enum LogLevel { - None, - Normal, - Detailed, - } /* * Functions callable from Rust */ unsafe extern "C++" { include!("bridge.hh"); + fn matches(self: &CredentialsHolder, str: &CxxString) -> bool; fn apiDiscovery(request: &Request, response: &mut Response) -> Result<()>; fn apiDiscoveryV1(request: &Request, response: &mut Response) -> Result<()>; fn apiServer(request: &Request, response: &mut Response) -> Result<()>; @@ -1110,18 +1105,5 @@ mod rustweb { fn jsonstat(request: &Request, response: &mut Response) -> Result<()>; fn prometheusMetrics(request: &Request, response: &mut Response) -> Result<()>; fn serveStuff(request: &Request, response: &mut Response) -> Result<()>; - - fn matches(self: &CredentialsHolder, str: &CxxString) -> bool; - fn comboaddress(address: &str) -> UniquePtr; - fn matches(nmg: &UniquePtr, address: &UniquePtr) -> bool; // match is a keyword - fn withValue(logger: &SharedPtr, key: &str, val: &str) -> SharedPtr; - fn log(logger: &SharedPtr, prio: Priority, msg: &str, values: &Vec); - fn error( - logger: &SharedPtr, - prio: Priority, - err: &str, - msg: &str, - values: &Vec, - ); } } diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index dbd35484c56b..b03a0c17309f 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -46,6 +46,7 @@ #include "settings/cxxsettings.hh" // IWYU pragma: keep, needed by included generated file #include "settings/rust/src/bridge.hh" #include "settings/rust/web.rs.h" +#include "settings/rust/misc.rs.h" using json11::Json; @@ -994,7 +995,7 @@ void serveRustWeb() for (const auto& address : listen.addresses) { tmp.addresses.emplace_back(address); } - tmp.tls = pdns::rust::web::rec::IncomingTLS{listen.tls.certificate, listen.tls.key, listen.tls.password}; + tmp.tls = pdns::rust::web::rec::IncomingTLS{listen.tls.certificate, listen.tls.key}; config.emplace_back(tmp); } } @@ -1020,17 +1021,17 @@ void serveRustWeb() } NetmaskGroup acl; acl.toMasks(::arg()["webserver-allow-from"]); - auto aclPtr = std::make_unique(acl); + auto aclPtr = std::make_unique(acl); auto logPtr = g_slog->withName("webserver"); - pdns::rust::web::rec::LogLevel loglevel = pdns::rust::web::rec::LogLevel::Normal; + pdns::rust::misc::LogLevel loglevel = pdns::rust::misc::LogLevel::Normal; auto configLevel = ::arg()["webserver-loglevel"]; if (configLevel == "none") { - loglevel = pdns::rust::web::rec::LogLevel::Normal; + loglevel = pdns::rust::misc::LogLevel::Normal; } else if (configLevel == "detailed") { - loglevel = pdns::rust::web::rec::LogLevel::Detailed; + loglevel = pdns::rust::misc::LogLevel::Detailed; } pdns::rust::web::rec::serveweb(config, ::rust::Slice{urls.data(), urls.size()}, std::move(password), std::move(apikey), std::move(aclPtr), std::move(logPtr), loglevel); } diff --git a/pdns/recursordist/ws-recursor.hh b/pdns/recursordist/ws-recursor.hh index 882d29ba4fb3..4be93d07263a 100644 --- a/pdns/recursordist/ws-recursor.hh +++ b/pdns/recursordist/ws-recursor.hh @@ -20,15 +20,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once -#include -#include "namespaces.hh" -#include "mplexer.hh" + #include "webserver.hh" class HttpRequest; class HttpResponse; +extern void serveRustWeb(); + +#ifndef RUST_WS + +#include +#include "namespaces.hh" +#include "mplexer.hh" -#if 0 class AsyncServer : public Server { public: diff --git a/pdns/webserver.hh b/pdns/webserver.hh index e542bc54f9b1..767f986d3ec0 100644 --- a/pdns/webserver.hh +++ b/pdns/webserver.hh @@ -21,6 +21,8 @@ */ #pragma once +#include "config.h" + #ifdef RECURSOR // Network facing/routing part of webserver is implemented in rust. We stil use a few classes from // yahttp, but do not link to it.