mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
dynamic subnet in port forward
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ -z "$sip" ] || [ -z "$dip" ] || [ -z "$sport" ] || [ -z "$dport" ]; then
|
if [ -z "$sip" ] || [ -z "$dip" ] || [ -z "$dprefix" ] || [ -z "$sport" ] || [ -z "$dport" ]; then
|
||||||
>&2 echo 'missing required env var'
|
>&2 echo 'missing required env var'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
NAME="F$(echo "$sip:$sport -> $dip:$dport" | sha256sum | head -c 15)"
|
NAME="F$(echo "$sip:$sport -> $dip/$dprefix:$dport" | sha256sum | head -c 15)"
|
||||||
|
|
||||||
for kind in INPUT FORWARD ACCEPT; do
|
for kind in INPUT FORWARD ACCEPT; do
|
||||||
if ! iptables -C $kind -j "${NAME}_${kind}" 2> /dev/null; then
|
if ! iptables -C $kind -j "${NAME}_${kind}" 2> /dev/null; then
|
||||||
@@ -40,10 +40,10 @@ iptables -t nat -A ${NAME}_PREROUTING -d "$sip" -p udp --dport "$sport" -j DNAT
|
|||||||
iptables -t nat -A ${NAME}_OUTPUT -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
iptables -t nat -A ${NAME}_OUTPUT -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
||||||
iptables -t nat -A ${NAME}_OUTPUT -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
iptables -t nat -A ${NAME}_OUTPUT -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
||||||
|
|
||||||
iptables -t nat -A ${NAME}_PREROUTING -s "$dip/24" -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
iptables -t nat -A ${NAME}_PREROUTING -s "$dip/$dprefix" -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
||||||
iptables -t nat -A ${NAME}_PREROUTING -s "$dip/24" -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
iptables -t nat -A ${NAME}_PREROUTING -s "$dip/$dprefix" -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
|
||||||
iptables -t nat -A ${NAME}_POSTROUTING -s "$dip/24" -d "$dip" -p tcp --dport "$dport" -j MASQUERADE
|
iptables -t nat -A ${NAME}_POSTROUTING -s "$dip/$dprefix" -d "$dip" -p tcp --dport "$dport" -j MASQUERADE
|
||||||
iptables -t nat -A ${NAME}_POSTROUTING -s "$dip/24" -d "$dip" -p udp --dport "$dport" -j MASQUERADE
|
iptables -t nat -A ${NAME}_POSTROUTING -s "$dip/$dprefix" -d "$dip" -p udp --dport "$dport" -j MASQUERADE
|
||||||
|
|
||||||
iptables -A ${NAME}_FORWARD -d $dip -p tcp --dport $dport -m state --state NEW -j ACCEPT
|
iptables -A ${NAME}_FORWARD -d $dip -p tcp --dport $dport -m state --state NEW -j ACCEPT
|
||||||
iptables -A ${NAME}_FORWARD -d $dip -p udp --dport $dport -m state --state NEW -j ACCEPT
|
iptables -A ${NAME}_FORWARD -d $dip -p udp --dport $dport -m state --state NEW -j ACCEPT
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ pub fn forward_api<C: Context>() -> ParentHandler<C> {
|
|||||||
struct ForwardMapping {
|
struct ForwardMapping {
|
||||||
source: SocketAddrV4,
|
source: SocketAddrV4,
|
||||||
target: SocketAddrV4,
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
rc: Weak<()>,
|
rc: Weak<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +92,7 @@ impl PortForwardState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
source: SocketAddrV4,
|
source: SocketAddrV4,
|
||||||
target: SocketAddrV4,
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
) -> Result<Arc<()>, Error> {
|
) -> Result<Arc<()>, Error> {
|
||||||
if let Some(existing) = self.mappings.get_mut(&source) {
|
if let Some(existing) = self.mappings.get_mut(&source) {
|
||||||
if existing.target == target {
|
if existing.target == target {
|
||||||
@@ -104,18 +106,19 @@ impl PortForwardState {
|
|||||||
} else {
|
} else {
|
||||||
// Different target, need to remove old and add new
|
// Different target, need to remove old and add new
|
||||||
if let Some(mapping) = self.mappings.remove(&source) {
|
if let Some(mapping) = self.mappings.remove(&source) {
|
||||||
unforward(mapping.source, mapping.target).await?;
|
unforward(mapping.source, mapping.target, mapping.target_prefix).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let rc = Arc::new(());
|
let rc = Arc::new(());
|
||||||
forward(source, target).await?;
|
forward(source, target, target_prefix).await?;
|
||||||
self.mappings.insert(
|
self.mappings.insert(
|
||||||
source,
|
source,
|
||||||
ForwardMapping {
|
ForwardMapping {
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
|
target_prefix,
|
||||||
rc: Arc::downgrade(&rc),
|
rc: Arc::downgrade(&rc),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -133,7 +136,7 @@ impl PortForwardState {
|
|||||||
|
|
||||||
for source in to_remove {
|
for source in to_remove {
|
||||||
if let Some(mapping) = self.mappings.remove(&source) {
|
if let Some(mapping) = self.mappings.remove(&source) {
|
||||||
unforward(mapping.source, mapping.target).await?;
|
unforward(mapping.source, mapping.target, mapping.target_prefix).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -154,7 +157,9 @@ impl Drop for PortForwardState {
|
|||||||
let mappings = std::mem::take(&mut self.mappings);
|
let mappings = std::mem::take(&mut self.mappings);
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
for (_, mapping) in mappings {
|
for (_, mapping) in mappings {
|
||||||
unforward(mapping.source, mapping.target).await.log_err();
|
unforward(mapping.source, mapping.target, mapping.target_prefix)
|
||||||
|
.await
|
||||||
|
.log_err();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -165,6 +170,7 @@ enum PortForwardCommand {
|
|||||||
AddForward {
|
AddForward {
|
||||||
source: SocketAddrV4,
|
source: SocketAddrV4,
|
||||||
target: SocketAddrV4,
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
respond: oneshot::Sender<Result<Arc<()>, Error>>,
|
respond: oneshot::Sender<Result<Arc<()>, Error>>,
|
||||||
},
|
},
|
||||||
Gc {
|
Gc {
|
||||||
@@ -244,9 +250,10 @@ impl PortForwardController {
|
|||||||
PortForwardCommand::AddForward {
|
PortForwardCommand::AddForward {
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
|
target_prefix,
|
||||||
respond,
|
respond,
|
||||||
} => {
|
} => {
|
||||||
let result = state.add_forward(source, target).await;
|
let result = state.add_forward(source, target, target_prefix).await;
|
||||||
respond.send(result).ok();
|
respond.send(result).ok();
|
||||||
}
|
}
|
||||||
PortForwardCommand::Gc { respond } => {
|
PortForwardCommand::Gc { respond } => {
|
||||||
@@ -270,12 +277,14 @@ impl PortForwardController {
|
|||||||
&self,
|
&self,
|
||||||
source: SocketAddrV4,
|
source: SocketAddrV4,
|
||||||
target: SocketAddrV4,
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
) -> Result<Arc<()>, Error> {
|
) -> Result<Arc<()>, Error> {
|
||||||
let (send, recv) = oneshot::channel();
|
let (send, recv) = oneshot::channel();
|
||||||
self.req
|
self.req
|
||||||
.send(PortForwardCommand::AddForward {
|
.send(PortForwardCommand::AddForward {
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
|
target_prefix,
|
||||||
respond: send,
|
respond: send,
|
||||||
})
|
})
|
||||||
.map_err(err_has_exited)?;
|
.map_err(err_has_exited)?;
|
||||||
@@ -305,6 +314,7 @@ impl PortForwardController {
|
|||||||
struct InterfaceForwardRequest {
|
struct InterfaceForwardRequest {
|
||||||
external: u16,
|
external: u16,
|
||||||
target: SocketAddrV4,
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
filter: DynInterfaceFilter,
|
filter: DynInterfaceFilter,
|
||||||
rc: Arc<()>,
|
rc: Arc<()>,
|
||||||
}
|
}
|
||||||
@@ -312,7 +322,7 @@ struct InterfaceForwardRequest {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct InterfaceForwardEntry {
|
struct InterfaceForwardEntry {
|
||||||
external: u16,
|
external: u16,
|
||||||
filter: BTreeMap<DynInterfaceFilter, (SocketAddrV4, Weak<()>)>,
|
filter: BTreeMap<DynInterfaceFilter, (SocketAddrV4, u8, Weak<()>)>,
|
||||||
// Maps source SocketAddr -> strong reference for the forward created in PortForwardController
|
// Maps source SocketAddr -> strong reference for the forward created in PortForwardController
|
||||||
forwards: BTreeMap<SocketAddrV4, Arc<()>>,
|
forwards: BTreeMap<SocketAddrV4, Arc<()>>,
|
||||||
}
|
}
|
||||||
@@ -343,12 +353,12 @@ impl InterfaceForwardEntry {
|
|||||||
let mut keep = BTreeSet::<SocketAddrV4>::new();
|
let mut keep = BTreeSet::<SocketAddrV4>::new();
|
||||||
|
|
||||||
for (iface, info) in ip_info.iter() {
|
for (iface, info) in ip_info.iter() {
|
||||||
if let Some(target) = self
|
if let Some((target, target_prefix)) = self
|
||||||
.filter
|
.filter
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, (_, rc))| rc.strong_count() > 0)
|
.filter(|(_, (_, _, rc))| rc.strong_count() > 0)
|
||||||
.find(|(filter, _)| filter.filter(iface, info))
|
.find(|(filter, _)| filter.filter(iface, info))
|
||||||
.map(|(_, (target, _))| *target)
|
.map(|(_, (target, target_prefix, _))| (*target, *target_prefix))
|
||||||
{
|
{
|
||||||
if let Some(ip_info) = &info.ip_info {
|
if let Some(ip_info) = &info.ip_info {
|
||||||
for addr in ip_info.subnets.iter().filter_map(|net| {
|
for addr in ip_info.subnets.iter().filter_map(|net| {
|
||||||
@@ -360,7 +370,9 @@ impl InterfaceForwardEntry {
|
|||||||
}) {
|
}) {
|
||||||
keep.insert(addr);
|
keep.insert(addr);
|
||||||
if !self.forwards.contains_key(&addr) {
|
if !self.forwards.contains_key(&addr) {
|
||||||
let rc = port_forward.add_forward(addr, target).await?;
|
let rc = port_forward
|
||||||
|
.add_forward(addr, target, target_prefix)
|
||||||
|
.await?;
|
||||||
self.forwards.insert(addr, rc);
|
self.forwards.insert(addr, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,6 +391,7 @@ impl InterfaceForwardEntry {
|
|||||||
InterfaceForwardRequest {
|
InterfaceForwardRequest {
|
||||||
external,
|
external,
|
||||||
target,
|
target,
|
||||||
|
target_prefix,
|
||||||
filter,
|
filter,
|
||||||
mut rc,
|
mut rc,
|
||||||
}: InterfaceForwardRequest,
|
}: InterfaceForwardRequest,
|
||||||
@@ -395,15 +408,16 @@ impl InterfaceForwardEntry {
|
|||||||
let entry = self
|
let entry = self
|
||||||
.filter
|
.filter
|
||||||
.entry(filter)
|
.entry(filter)
|
||||||
.or_insert_with(|| (target, Arc::downgrade(&rc)));
|
.or_insert_with(|| (target, target_prefix, Arc::downgrade(&rc)));
|
||||||
if entry.0 != target {
|
if entry.0 != target {
|
||||||
entry.0 = target;
|
entry.0 = target;
|
||||||
entry.1 = Arc::downgrade(&rc);
|
entry.1 = target_prefix;
|
||||||
|
entry.2 = Arc::downgrade(&rc);
|
||||||
}
|
}
|
||||||
if let Some(existing) = entry.1.upgrade() {
|
if let Some(existing) = entry.2.upgrade() {
|
||||||
rc = existing;
|
rc = existing;
|
||||||
} else {
|
} else {
|
||||||
entry.1 = Arc::downgrade(&rc);
|
entry.2 = Arc::downgrade(&rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update(ip_info, port_forward).await?;
|
self.update(ip_info, port_forward).await?;
|
||||||
@@ -416,7 +430,7 @@ impl InterfaceForwardEntry {
|
|||||||
ip_info: &OrdMap<GatewayId, NetworkInterfaceInfo>,
|
ip_info: &OrdMap<GatewayId, NetworkInterfaceInfo>,
|
||||||
port_forward: &PortForwardController,
|
port_forward: &PortForwardController,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.filter.retain(|_, (_, rc)| rc.strong_count() > 0);
|
self.filter.retain(|_, (_, _, rc)| rc.strong_count() > 0);
|
||||||
|
|
||||||
self.update(ip_info, port_forward).await
|
self.update(ip_info, port_forward).await
|
||||||
}
|
}
|
||||||
@@ -474,6 +488,7 @@ pub struct ForwardTable(pub BTreeMap<u16, ForwardTarget>);
|
|||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct ForwardTarget {
|
pub struct ForwardTarget {
|
||||||
pub target: SocketAddrV4,
|
pub target: SocketAddrV4,
|
||||||
|
pub target_prefix: u8,
|
||||||
pub filter: String,
|
pub filter: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,12 +502,13 @@ impl From<&InterfaceForwardState> for ForwardTable {
|
|||||||
entry
|
entry
|
||||||
.filter
|
.filter
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, (_, rc))| rc.strong_count() > 0)
|
.filter(|(_, (_, _, rc))| rc.strong_count() > 0)
|
||||||
.map(|(filter, (target, _))| {
|
.map(|(filter, (target, target_prefix, _))| {
|
||||||
(
|
(
|
||||||
entry.external,
|
entry.external,
|
||||||
ForwardTarget {
|
ForwardTarget {
|
||||||
target: *target,
|
target: *target,
|
||||||
|
target_prefix: *target_prefix,
|
||||||
filter: format!("{:#?}", filter),
|
filter: format!("{:#?}", filter),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -573,6 +589,7 @@ impl InterfacePortForwardController {
|
|||||||
external: u16,
|
external: u16,
|
||||||
filter: DynInterfaceFilter,
|
filter: DynInterfaceFilter,
|
||||||
target: SocketAddrV4,
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
) -> Result<Arc<()>, Error> {
|
) -> Result<Arc<()>, Error> {
|
||||||
let rc = Arc::new(());
|
let rc = Arc::new(());
|
||||||
let (send, recv) = oneshot::channel();
|
let (send, recv) = oneshot::channel();
|
||||||
@@ -581,6 +598,7 @@ impl InterfacePortForwardController {
|
|||||||
InterfaceForwardRequest {
|
InterfaceForwardRequest {
|
||||||
external,
|
external,
|
||||||
target,
|
target,
|
||||||
|
target_prefix,
|
||||||
filter,
|
filter,
|
||||||
rc,
|
rc,
|
||||||
},
|
},
|
||||||
@@ -609,10 +627,15 @@ impl InterfacePortForwardController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn forward(source: SocketAddrV4, target: SocketAddrV4) -> Result<(), Error> {
|
async fn forward(
|
||||||
|
source: SocketAddrV4,
|
||||||
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
|
) -> Result<(), Error> {
|
||||||
Command::new("/usr/lib/startos/scripts/forward-port")
|
Command::new("/usr/lib/startos/scripts/forward-port")
|
||||||
.env("sip", source.ip().to_string())
|
.env("sip", source.ip().to_string())
|
||||||
.env("dip", target.ip().to_string())
|
.env("dip", target.ip().to_string())
|
||||||
|
.env("dprefix", target_prefix.to_string())
|
||||||
.env("sport", source.port().to_string())
|
.env("sport", source.port().to_string())
|
||||||
.env("dport", target.port().to_string())
|
.env("dport", target.port().to_string())
|
||||||
.invoke(ErrorKind::Network)
|
.invoke(ErrorKind::Network)
|
||||||
@@ -620,11 +643,16 @@ async fn forward(source: SocketAddrV4, target: SocketAddrV4) -> Result<(), Error
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unforward(source: SocketAddrV4, target: SocketAddrV4) -> Result<(), Error> {
|
async fn unforward(
|
||||||
|
source: SocketAddrV4,
|
||||||
|
target: SocketAddrV4,
|
||||||
|
target_prefix: u8,
|
||||||
|
) -> Result<(), Error> {
|
||||||
Command::new("/usr/lib/startos/scripts/forward-port")
|
Command::new("/usr/lib/startos/scripts/forward-port")
|
||||||
.env("UNDO", "1")
|
.env("UNDO", "1")
|
||||||
.env("sip", source.ip().to_string())
|
.env("sip", source.ip().to_string())
|
||||||
.env("dip", target.ip().to_string())
|
.env("dip", target.ip().to_string())
|
||||||
|
.env("dprefix", target_prefix.to_string())
|
||||||
.env("sport", source.port().to_string())
|
.env("sport", source.port().to_string())
|
||||||
.env("dport", target.port().to_string())
|
.env("dport", target.port().to_string())
|
||||||
.invoke(ErrorKind::Network)
|
.invoke(ErrorKind::Network)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
@@ -693,7 +693,24 @@ impl NetServiceData {
|
|||||||
(
|
(
|
||||||
internal,
|
internal,
|
||||||
filter.clone(),
|
filter.clone(),
|
||||||
ctrl.forward.add(external, filter, internal).await?,
|
ctrl.forward
|
||||||
|
.add(
|
||||||
|
external,
|
||||||
|
filter,
|
||||||
|
internal,
|
||||||
|
net_ifaces
|
||||||
|
.iter()
|
||||||
|
.find_map(|(_, i)| {
|
||||||
|
i.ip_info.as_ref().and_then(|i| {
|
||||||
|
i.subnets.iter().find(|i| {
|
||||||
|
i.contains(&IpAddr::from(*internal.ip()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map(|s| s.prefix_len())
|
||||||
|
.unwrap_or(32),
|
||||||
|
)
|
||||||
|
.await?,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Stdio;
|
||||||
use std::sync::{Arc, LazyLock, OnceLock};
|
use std::sync::{Arc, LazyLock, OnceLock};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@@ -39,6 +40,7 @@ pub static CONTAINER_TOOL: LazyLock<&'static str> = LazyLock::new(|| {
|
|||||||
if *PREFER_DOCKER.get_or_init(|| false) {
|
if *PREFER_DOCKER.get_or_init(|| false) {
|
||||||
if std::process::Command::new("which")
|
if std::process::Command::new("which")
|
||||||
.arg("docker")
|
.arg("docker")
|
||||||
|
.stdout(Stdio::null())
|
||||||
.status()
|
.status()
|
||||||
.map_or(false, |o| o.success())
|
.map_or(false, |o| o.success())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -435,7 +435,22 @@ pub async fn add_forward(
|
|||||||
ctx: TunnelContext,
|
ctx: TunnelContext,
|
||||||
AddPortForwardParams { source, target }: AddPortForwardParams,
|
AddPortForwardParams { source, target }: AddPortForwardParams,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let rc = ctx.forward.add_forward(source, target).await?;
|
let prefix = ctx
|
||||||
|
.net_iface
|
||||||
|
.peek(|i| {
|
||||||
|
i.iter()
|
||||||
|
.find_map(|(_, i)| {
|
||||||
|
i.ip_info.as_ref().and_then(|i| {
|
||||||
|
i.subnets
|
||||||
|
.iter()
|
||||||
|
.find(|s| s.contains(&IpAddr::from(*target.ip())))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
|
})
|
||||||
|
.map(|s| s.prefix_len())
|
||||||
|
.unwrap_or(32);
|
||||||
|
let rc = ctx.forward.add_forward(source, target, prefix).await?;
|
||||||
ctx.active_forwards.mutate(|m| {
|
ctx.active_forwards.mutate(|m| {
|
||||||
m.insert(source, rc);
|
m.insert(source, rc);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -185,7 +185,21 @@ impl TunnelContext {
|
|||||||
|
|
||||||
let mut active_forwards = BTreeMap::new();
|
let mut active_forwards = BTreeMap::new();
|
||||||
for (from, to) in peek.as_port_forwards().de()?.0 {
|
for (from, to) in peek.as_port_forwards().de()?.0 {
|
||||||
active_forwards.insert(from, forward.add_forward(from, to).await?);
|
let prefix = net_iface
|
||||||
|
.peek(|i| {
|
||||||
|
i.iter()
|
||||||
|
.find_map(|(_, i)| {
|
||||||
|
i.ip_info.as_ref().and_then(|i| {
|
||||||
|
i.subnets
|
||||||
|
.iter()
|
||||||
|
.find(|s| s.contains(&IpAddr::from(*to.ip())))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
|
})
|
||||||
|
.map(|s| s.prefix_len())
|
||||||
|
.unwrap_or(32);
|
||||||
|
active_forwards.insert(from, forward.add_forward(from, to, prefix).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(Arc::new(TunnelContextSeed {
|
Ok(Self(Arc::new(TunnelContextSeed {
|
||||||
|
|||||||
Reference in New Issue
Block a user