use std::{net::SocketAddr, sync::Arc};
use shadowsocks::{
config::ServerType,
context::{Context, SharedContext},
dns_resolver::DnsResolver,
net::ConnectOpts,
relay::Address,
};
use crate::{acl::AccessControl, config::SecurityConfig, net::FlowStat};
#[derive(Clone)]
pub struct ServiceContext {
context: SharedContext,
connect_opts: ConnectOpts,
acl: Option<Arc<AccessControl>>,
flow_stat: Arc<FlowStat>,
}
impl Default for ServiceContext {
fn default() -> Self {
Self {
context: Context::new_shared(ServerType::Server),
connect_opts: ConnectOpts::default(),
acl: None,
flow_stat: Arc::new(FlowStat::new()),
}
}
}
impl ServiceContext {
pub fn new() -> Self {
Self::default()
}
pub fn context(&self) -> SharedContext {
self.context.clone()
}
pub fn context_ref(&self) -> &Context {
self.context.as_ref()
}
pub fn set_connect_opts(&mut self, connect_opts: ConnectOpts) {
self.connect_opts = connect_opts;
}
pub fn connect_opts_ref(&self) -> &ConnectOpts {
&self.connect_opts
}
pub fn set_acl(&mut self, acl: Arc<AccessControl>) {
self.acl = Some(acl);
}
pub fn acl(&self) -> Option<&AccessControl> {
self.acl.as_deref()
}
pub fn flow_stat(&self) -> Arc<FlowStat> {
self.flow_stat.clone()
}
pub fn flow_stat_ref(&self) -> &FlowStat {
self.flow_stat.as_ref()
}
pub fn set_dns_resolver(&mut self, resolver: Arc<DnsResolver>) {
let context = Arc::get_mut(&mut self.context).expect("cannot set DNS resolver on a shared context");
context.set_dns_resolver(resolver)
}
pub fn dns_resolver(&self) -> &DnsResolver {
self.context.dns_resolver()
}
pub async fn check_outbound_blocked(&self, addr: &Address) -> bool {
match self.acl {
None => false,
Some(ref acl) => acl.check_outbound_blocked(&self.context, addr).await,
}
}
pub fn check_client_blocked(&self, addr: &SocketAddr) -> bool {
match self.acl {
None => false,
Some(ref acl) => acl.check_client_blocked(addr),
}
}
pub fn set_ipv6_first(&mut self, ipv6_first: bool) {
let context = Arc::get_mut(&mut self.context).expect("cannot set ipv6_first on a shared context");
context.set_ipv6_first(ipv6_first);
}
pub fn set_security_config(&mut self, security: &SecurityConfig) {
let context = Arc::get_mut(&mut self.context).expect("cannot set security on a shared context");
context.set_replay_attack_policy(security.replay_attack.policy);
}
}