Skip to content

fix: also bind private addresses to support LXC containers - #11

Merged
hpk42 merged 2 commits into
mainfrom
hpk/underscore
Mar 5, 2026
Merged

fix: also bind private addresses to support LXC containers#11
hpk42 merged 2 commits into
mainfrom
hpk/underscore

Conversation

@hpk42

@hpk42 hpk42 commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

The chatmail-turn server discovered its listen addresses by calling interface.global_ip_addrs() via the netdev crate. This method filters out any addresses that are not globally routable.

In LXC containers, network interfaces typically only have private RFC 1918 addresses (e.g., 10.x.x.x). As a result, the address list was returning empty, causing the server to exit immediately with ErrNoAvailableConns. This caused the relay's turnserver.service systemd unit to enter a failed state inside containerized deployments.

@hpk42 hpk42 changed the title fix: bind private addresses to support LXC containers fix: also bind private addresses to support LXC containers Mar 2, 2026
@hpk42 hpk42 changed the title fix: also bind private addresses to support LXC containers WIP fix: also bind private addresses to support LXC containers Mar 2, 2026
@hpk42 hpk42 changed the title WIP fix: also bind private addresses to support LXC containers fix: also bind private addresses to support LXC containers Mar 2, 2026
@hpk42
hpk42 force-pushed the hpk/underscore branch 2 times, most recently from 342d313 to aa5358b Compare March 2, 2026 13:28
Comment thread src/main.rs Outdated
Comment thread src/main.rs Outdated
/// 2. Binding to an IPv6 link-local address requires a Scope ID (interface index),
/// otherwise the OS returns EINVAL (Invalid Argument).
fn is_link_local(ip: IpAddr) -> bool {
// Note: As of Rust 1.93, a unified IpAddr::is_link_local() method on the enum remains unstable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no IpAddr::is_link_local(), no stable, no unstable, not in Rust 1.93, not in the linked issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i had looked at rust-lang/rust#27709 (comment) but didn't notice it was from 2015. I was lead to that issue by some search on why "IpAddr::is_link_local" does not exist, but only briefly looked. I removed the misleading comments.

Comment thread src/main.rs
relay_addr_generator: Box::new(RelayAddressGeneratorStatic {
relay_address: public_ip,
address: public_ip.to_string(),
relay_address: listen_ip,

@DarkCat09 DarkCat09 Mar 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A client sends an address allocation TURN request, a server responds with an allocated IP + port. This relay_address is what's sent in the response.

Since you allow local IPs now and they don't get filtered out when enumerating interfaces, a RelayAddressGenerator may be instantiated with a local IP in relay_address. On the client's side, such an IP is not valid (because the client obviously has a different local network).

Note that i may be completely mistaken as i've never written TURN servers :3
We should probably test this change.
But as far as i can see -- local IPs will be given to clients and cause TURN connection errors.

If that's true, then i suggest requesting a server's public address from an external HTTP server like icanhazip dot com, or simply rejecting starting TURN server when no public IPs are found in the available interfaces (the current behavior) and no relay address is specified in CLI args (#12)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand each socket has its own config, so local IPs will only be given to clients that connect from the local network. For real deployments it does not matter because clients will be connected from the internet, this change is only for testing on the local network.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok if it's the purpose of this pull request

Judging by the title, i thought @hpk42 wanted to run a TURN server inside a container and forward ports to the host, on a real deployment with a public IP (which is unavailable inside a container)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK it's about running chatmail relay and simulated client in the same local virtual LXC network, for development setup. It is not for production deployment in LXC.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it makes sense, thanks

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, PR title is misleading in that sense, sorry. It is indeed meant for testing. merging it now. we can iterate.

@hpk42
hpk42 merged commit 7661ca7 into main Mar 5, 2026
4 checks passed
@hpk42
hpk42 deleted the hpk/underscore branch March 5, 2026 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants