Get local IP address
My application listens on 0.0.0.0:80 and 0.0.0.0:443. My server has multiple network cards with different IP addresses. I need to get my local interface IP address where the client is connecting to. In raw axum::serve I can use the following:
#[derive(Clone, Debug)]
pub struct LocalSocketInfo {
pub local_addr: IpAddr,
}
impl Connected<IncomingStream<'_, TcpListener>> for LocalSocketInfo {
fn connect_info(target: IncomingStream<'_, TcpListener>) -> Self {
LocalSocketInfo {
local_addr: target.io().local_addr().unwrap().ip(),
}
}
}
However when using axum-server and openssl, it is impossible to get this information.
Have you tried using a Handle and then calling Handle::listening method?
@programatik29 Thanks for the reply!
With Handle::listening you always get the address you are listening to (e.g. "0.0.0.0:443" in my case). What I actually need is the local address of the specific TCP stream, not listener (which is only obtainable from tokio::net::tcp::stream::TcpStream::local_addr).
For example, say I have two ethernet cards on my server, eth0 and eth1. eth0 has address of 1.2.3.4, and eth1 has address of 4.5.6.7. I would like to tell the client is connecting through which interface, therefore I need to get local_addr from the exact TcpStream the client is connecting to. If the client is connecting from eth0, the local_addr in LocalSocketInfo would be 1.2.3.4.
To demonstrate my rough idea, I added a simple demo commit to my fork:
https://github.com/showier-drastic/axum-server/commit/de2dfad3e956b22a84ecd99d8f0d9eeb096c683f
When using the forked version of axum-server, I can use the following code:
impl Connected<(SocketAddr, SocketAddr)> for LocalSocketInfo {
fn connect_info(target: (SocketAddr, SocketAddr)) -> Self {
LocalSocketInfo {
local_addr: target.0.ip(),
}
}
}
Oh okay, got it. In that case you could create a custom struct that implements Accept. Get the local address from io stream and add it to extensions using AddExtension from tower-http crate.