Compare commits

..

10 Commits

Author SHA1 Message Date
Jade Ellis 5d2e840859 feat: Enable direct_tls and more logging by default
Disables additional logging on maxperf builds
2026-07-09 22:44:26 +01:00
Ginger 2fabf18451 style: Fix comment 2026-07-09 17:36:56 -04:00
Ginger 63a26141f8 fix: Make depth cap a bit more thorough 2026-07-09 17:33:13 -04:00
Ginger cc1f667c2b fix: Cap max_depth to 50 in hierarchy endpoint 2026-07-09 17:22:36 -04:00
Ginger 89dcda4c3c feat: Kill roomsynctoken_shortstatehash dead 2026-07-09 16:43:10 -04:00
timedout 62730e861a style: Use string literals instead of u8s 2026-07-09 19:40:11 +00:00
timedout 68d018bd37 style: Use string literals instead of u8s 2026-07-09 19:40:11 +00:00
timedout 959370169a chore: Rename changelog file 2026-07-09 19:40:11 +00:00
timedout f71f6e922c feat: Allow configuring the desired client IP source 2026-07-09 19:40:11 +00:00
theS1LV3R ce185aff13 docs: Update docs to match new resolver query command 2026-07-09 19:21:59 +00:00
13 changed files with 113 additions and 11 deletions
+2
View File
@@ -74,6 +74,7 @@ jobs:
CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }}
TARGET_CPU=
RUST_PROFILE=release
CARGO_FEATURES=default
platforms: ${{ matrix.platform }}
labels: ${{ steps.prepare.outputs.metadata_labels }}
annotations: ${{ steps.prepare.outputs.metadata_annotations }}
@@ -161,6 +162,7 @@ jobs:
CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }}
TARGET_CPU=${{ matrix.target_cpu }}
RUST_PROFILE=release-max-perf
CARGO_FEATURES=default,release_max_log_level
platforms: ${{ matrix.platform }}
labels: ${{ steps.prepare.outputs.metadata_labels }}
annotations: ${{ steps.prepare.outputs.metadata_annotations }}
+1
View File
@@ -0,0 +1 @@
Added a configuration option to allow choosing a client IP source that is not the TCP connecting IP. Contributed by @nex.
+1
View File
@@ -0,0 +1 @@
Enable `direct_tls` and more logging by default
+1 -1
View File
@@ -1 +1 @@
Adjusted legacy sync logic to no longer use the `roomsynctoken_shortstatehash` database column. Once this change has been confirmed to be stable and reliable, a future update will remove it entirely, significantly decreasing database sizes. Contributed by @ginger.
Adjusted legacy sync logic to allow the `roomsynctoken_shortstatehash` database column to be dropped, massively reducing database sizes, especially for old deployments. Contributed by @ginger.
+21
View File
@@ -290,6 +290,27 @@
#
#ip_lookup_strategy = 5
# The source to use for discovering the real connecting client IP.
#
# Takes any of the following options:
#
# "cf_connecting_ip" - `Cf-Connecting-Ip` header
# "cloudfront_viewer_address" - `CloudFront-Viewer-Address` header
# "fly_client_ip" - `Fly-Client-IP` header
# "x_forwarded_for" - rightmost value of the `X-Forwarded-For` header
# "true_client_ip" - `True-Client-Ip` header
# "x_envoy_external_address" - `X-Envoy-External-Address` header
# "x_real_ip" - `X-Real-Ip` header
#
# Only set this if you are certain only your reverse proxy
# will send the expected header. There is no "is the connecting IP allowed
# to set this header" check; if the header selected is present, it is
# used.
#
# Defaults to the IP address actually making the connection.
#
#request_ip_source = false
# Max request size for file uploads in bytes. Defaults to 20MB.
# Also limits incoming federated media.
#
+3 -5
View File
@@ -104,13 +104,11 @@ ## `!admin query resolver`
resolver service
### `!admin query resolver destinations-cache`
### `!admin query resolver cache`
Query the destinations cache
Query the destinations or overrides cache
### `!admin query resolver overrides-cache`
Query the overrides cache
Shows entire cache by default, but can be narrowed to only show overrides with `-o/--overrides true`, or to exclude them with `false`
### `!admin query resolver flush-cache`
+5 -2
View File
@@ -36,14 +36,16 @@
self'.packages.stable-toolchain
);
# extra features via `cargoExtraArgs`
cargoExtraArgs = "-F http3";
default = pkgs.callPackage ./continuwuity.nix {
inherit self craneLib;
liburing = (if isStatic then pkgs.pkgsStatic else pkgs).liburing;
rocksdb = if isStatic then null else self'.packages.rocksdb;
# extra features via `cargoExtraArgs`
cargoExtraArgs = "-F http3";
inherit cargoExtraArgs;
# extra RUSTFLAGS via `rustflags`
# the stuff below is required for http3
rustflags = "--cfg reqwest_unstable";
@@ -55,6 +57,7 @@
max-perf = default.override {
# compiles slower but with more thorough optimizations
profile = "release-max-perf";
cargoExtraArgs = cargoExtraArgs + "-F release_max_log_level";
};
max-perf-haswell = max-perf.override {
+21
View File
@@ -370,6 +370,27 @@ pub struct Config {
#[serde(default = "default_ip_lookup_strategy")]
pub ip_lookup_strategy: u8,
/// The source to use for discovering the real connecting client IP.
///
/// Takes any of the following options:
///
/// "cf_connecting_ip" - `Cf-Connecting-Ip` header
/// "cloudfront_viewer_address" - `CloudFront-Viewer-Address` header
/// "fly_client_ip" - `Fly-Client-IP` header
/// "x_forwarded_for" - rightmost value of the `X-Forwarded-For` header
/// "true_client_ip" - `True-Client-Ip` header
/// "x_envoy_external_address" - `X-Envoy-External-Address` header
/// "x_real_ip" - `X-Real-Ip` header
///
/// Only set this if you are certain only your reverse proxy
/// will send the expected header. There is no "is the connecting IP allowed
/// to set this header" check; if the header selected is present, it is
/// used.
///
/// Defaults to the IP address actually making the connection.
#[serde(default)]
pub request_ip_source: Option<String>,
/// Max request size for file uploads in bytes. Defaults to 20MB.
/// Also limits incoming federated media.
///
+7 -1
View File
@@ -17,7 +17,7 @@
},
};
use conduwuit::{Err, Result, debug, info, warn};
use conduwuit::{Err, Result, debug, err, info, warn};
use rocksdb::{
AsColumnFamilyRef, BoundColumnFamily, DBCommon, DBWithThreadMode, MultiThreaded,
WaitForCompactOptions,
@@ -127,6 +127,12 @@ pub fn current_sequence(&self) -> u64 {
sequence
}
pub fn drop_column(&self, name: &str) -> Result {
self.db
.drop_cf(name)
.map_err(|err| err!("Failed to drop {name}: {err}"))
}
}
impl Drop for Engine {
+1 -1
View File
@@ -42,12 +42,12 @@ assets = [
[features]
default = [
"standard",
"release_max_log_level",
"ring",
"bindgen-runtime", # replace with bindgen-static on alpine
]
standard = [
"brotli_compression",
"direct_tls",
"element_hacks",
"gzip_compression",
"io_uring",
+17 -1
View File
@@ -48,6 +48,22 @@ pub(crate) fn build(services: &Arc<Services>) -> Result<(Router, Guard)> {
))]
let layers = layers.layer(compression_layer(server));
let client_ip_layer = match services
.config
.request_ip_source
.as_ref()
.map(AsRef::as_ref)
{
| Some("cf_connecting_ip") => ClientIpSource::CfConnectingIp,
| Some("cloudfront_viewer_address") => ClientIpSource::CloudFrontViewerAddress,
| Some("fly_client_ip") => ClientIpSource::FlyClientIp,
| Some("x_forwarded_for") => ClientIpSource::RightmostXForwardedFor,
| Some("true_client_ip") => ClientIpSource::TrueClientIp,
| Some("x_envoy_external_address") => ClientIpSource::XEnvoyExternalAddress,
| Some("x_real_ip") => ClientIpSource::XRealIp,
| None | Some(_) => ClientIpSource::ConnectInfo,
};
let services_ = services.clone();
let layers = layers
.layer(SetSensitiveHeadersLayer::new([header::AUTHORIZATION]))
@@ -59,7 +75,7 @@ pub(crate) fn build(services: &Arc<Services>) -> Result<(Router, Guard)> {
.on_response(DefaultOnResponse::new().level(Level::DEBUG)),
)
.layer(axum::middleware::from_fn_with_state(Arc::clone(services), request::handle))
.layer(ClientIpSource::ConnectInfo.into_extension())
.layer(client_ip_layer.into_extension())
.layer(ResponseBodyTimeoutLayer::new(Duration::from_secs(
server.config.client_response_timeout,
)))
+24
View File
@@ -240,6 +240,19 @@ async fn migrate(services: &Services) -> Result<()> {
.map_err(|e| err!("Failed to run 'split_userid_password' migration': {e}"))?;
}
if db["global"]
.get(DROP_ROOMSYNCTOKEN_SHORTSTATEHASH)
.await
.is_not_found()
{
info!("Running migration 'drop_roomsynctoken_shortstatehash'");
obliterate_roomsynctoken_shortstatehash_with_extreme_prejudice(services)
.await
.map_err(|e| {
err!("Failed to run 'drop_roomsynctoken_shortstatehash' migration': {e}")
})?;
}
assert_eq!(
services.globals.db.database_version().await,
DATABASE_VERSION,
@@ -873,3 +886,14 @@ async fn split_userid_password(services: &Services) -> Result {
db.db.sort()?;
Ok(())
}
const DROP_ROOMSYNCTOKEN_SHORTSTATEHASH: &str = "drop_roomsynctoken_shortstatehash";
async fn obliterate_roomsynctoken_shortstatehash_with_extreme_prejudice(
services: &Services,
) -> Result {
services.db.db.drop_column("roomsynctoken_shortstatehash")?;
info!("Cleared roomsynctoken_shortstatehash.");
Ok(())
}
+9
View File
@@ -263,6 +263,15 @@ pub async fn get_room_hierarchy_for_user(
continue;
}
// Bail out if queue length exceeds 50 to keep cycles in the space graph from
// blowing up the traversal. If you actually have over fifty nested spaces,
// and you're looking at this function to figure out what the issue is, I
// suggest you reconsider some of the choices you made which led you to this
// point.
if queue.len() > 50 {
return Err!("Space hierarchy is unreasonably large");
}
// Add accessible children as a new layer
if !summary.children.is_empty() {
queue.push(summary.children);