Skip to content

Commit 2e9b3a5

Browse files
committed
add netif outbound resolver
1 parent 11e1191 commit 2e9b3a5

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

ytflow-bin-shared/src/edit/gen/plugins.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ impl PluginType {
342342
}),
343343
PluginType::Netif => cbor!(NetifFactory {
344344
family_preference: FamilyPreference::Ipv4Only,
345-
selection: SelectionMode::Manual("eth0".into())
345+
selection: SelectionMode::Manual("eth0".into()),
346+
outbound_resolver: None,
346347
}),
347348
}
348349
.unwrap(),

ytflow/src/config/plugin/netif.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,27 @@ use crate::config::*;
55
use crate::plugin::netif;
66

77
#[derive(Serialize, Deserialize)]
8-
pub struct NetifFactory {
8+
pub struct NetifFactory<'a> {
99
pub family_preference: netif::FamilyPreference,
1010
#[serde(flatten)]
1111
pub selection: netif::SelectionMode,
12+
pub outbound_resolver: Option<&'a str>,
1213
}
1314

14-
impl NetifFactory {
15-
pub(in super::super) fn parse(plugin: &Plugin) -> ConfigResult<ParsedPlugin<'static, Self>> {
15+
impl<'de> NetifFactory<'de> {
16+
pub(in super::super) fn parse(plugin: &'de Plugin) -> ConfigResult<ParsedPlugin<'de, Self>> {
1617
let Plugin { name, param, .. } = plugin;
1718
let config: Self = parse_param(name, param)?;
1819
Ok(ParsedPlugin {
20+
requires: config
21+
.outbound_resolver
22+
.iter()
23+
.map(|r| Descriptor {
24+
descriptor: *r,
25+
r#type: AccessPointType::RESOLVER,
26+
})
27+
.collect(),
1928
factory: config,
20-
requires: vec![],
2129
provides: vec![
2230
Descriptor {
2331
descriptor: name.to_string() + ".tcp",
@@ -37,10 +45,32 @@ impl NetifFactory {
3745
}
3846
}
3947

40-
impl Factory for NetifFactory {
48+
impl<'a> Factory for NetifFactory<'a> {
4149
#[cfg(feature = "plugins")]
4250
fn load(&mut self, plugin_name: String, set: &mut PartialPluginSet) -> LoadResult<()> {
43-
let netif = netif::NetifSelector::new(self.selection.clone(), self.family_preference);
51+
use crate::plugin::null::Null;
52+
53+
let mut err = None;
54+
let netif =
55+
netif::NetifSelector::new(self.selection.clone(), self.family_preference, |weak| {
56+
set.stream_outbounds
57+
.insert(plugin_name.clone() + ".tcp", weak.clone());
58+
set.datagram_outbounds
59+
.insert(plugin_name.clone() + ".udp", weak.clone());
60+
set.resolver
61+
.insert(plugin_name.clone() + ".resolver", weak.clone());
62+
63+
self.outbound_resolver.map(|outbound_resolver| {
64+
set.get_or_create_resolver(plugin_name.clone(), outbound_resolver)
65+
.unwrap_or_else(|e| {
66+
err = Some(e);
67+
Arc::downgrade(&(Arc::new(Null) as _))
68+
})
69+
})
70+
});
71+
if let Some(err) = err {
72+
set.errors.push(err);
73+
}
4474
set.control_hub.create_plugin_control(
4575
plugin_name.clone(),
4676
"netif",

ytflow/src/plugin/netif/selector.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@ pub struct NetifSelector {
1111
pub(super) cached_netif: ArcSwap<sys::Netif>,
1212
provider: sys::NetifProvider,
1313
resolver: sys::Resolver,
14+
outbound_resolver: Option<Weak<dyn Resolver>>,
1415
me: Weak<Self>,
1516
}
1617

1718
impl NetifSelector {
18-
pub fn new(selection: SelectionMode, prefer: FamilyPreference) -> Arc<Self> {
19+
pub fn new(
20+
selection: SelectionMode,
21+
prefer: FamilyPreference,
22+
create_outbound_resolver: impl FnOnce(&Weak<Self>) -> Option<Weak<dyn Resolver>>,
23+
) -> Arc<Self> {
1924
let dummy_netif = sys::Netif {
2025
name: String::from("dummy_netif_awaiting_change"),
2126
..sys::Netif::default()
2227
};
2328
Arc::<Self>::new_cyclic(|this| {
29+
let outbound_resolver = create_outbound_resolver(this);
2430
let this = this.clone();
2531
let provider = sys::NetifProvider::new({
2632
let this = this.clone();
@@ -35,6 +41,7 @@ impl NetifSelector {
3541
cached_netif: ArcSwap::new(Arc::new(dummy_netif)),
3642
provider,
3743
resolver: sys::Resolver::new(this.clone()),
44+
outbound_resolver,
3845
me: this,
3946
}
4047
})
@@ -72,9 +79,15 @@ impl StreamOutboundFactory for NetifSelector {
7279
) -> FlowResult<(Box<dyn Stream>, Buffer)> {
7380
let preference = self.selection.load().1;
7481
let netif = self.cached_netif.load();
82+
let resolver = self
83+
.outbound_resolver
84+
.as_ref()
85+
.map(|r| r.upgrade().ok_or(FlowError::NoOutbound))
86+
.transpose()?
87+
.unwrap_or_else(|| self.me.upgrade().unwrap());
7588
crate::plugin::socket::dial_stream(
7689
context,
77-
self.me.upgrade().unwrap(),
90+
resolver,
7891
// A workaround for E0308 "one type is more general than the other"
7992
// https://github.com/rust-lang/rust/issues/70263
8093
Some(|s: &mut _| sys::bind_socket_v4(&netif, s)).filter(|_| {
@@ -100,9 +113,15 @@ impl DatagramSessionFactory for NetifSelector {
100113
async fn bind(&self, context: Box<FlowContext>) -> FlowResult<Box<dyn DatagramSession>> {
101114
let preference = self.selection.load().1;
102115
let netif = self.cached_netif.load_full();
116+
let resolver = self
117+
.outbound_resolver
118+
.as_ref()
119+
.map(|r| r.upgrade().ok_or(FlowError::NoOutbound))
120+
.transpose()?
121+
.unwrap_or_else(|| self.me.upgrade().unwrap());
103122
crate::plugin::socket::dial_datagram_session(
104123
&context,
105-
self.me.upgrade().unwrap(),
124+
resolver,
106125
// A workaround for E0308 "one type is more general than the other"
107126
// https://github.com/rust-lang/rust/issues/70263
108127
Some({

0 commit comments

Comments
 (0)