taxy/proxy/
mod.rs

1use self::{http::HttpPortContext, tcp::TcpPortContext, udp::UdpPortContext};
2use crate::server::cert_list::CertList;
3use once_cell::sync::OnceCell;
4use taxy_api::error::Error;
5use taxy_api::multiaddr::Multiaddr;
6use taxy_api::port::{PortStatus, SocketState};
7use taxy_api::{
8    port::{Port, PortEntry},
9    proxy::ProxyEntry,
10};
11
12pub mod http;
13pub mod tcp;
14pub mod tls;
15pub mod udp;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum PortContextEvent {
19    SocketStateUpdated(SocketState),
20}
21
22#[derive(Debug)]
23pub struct PortContext {
24    pub entry: PortEntry,
25    pub kind: PortContextKind,
26}
27
28impl PortContext {
29    pub fn new(entry: PortEntry) -> Result<Self, Error> {
30        let kind = if entry.port.listen.is_quic() {
31            PortContextKind::Http3(HttpPortContext::new(&entry)?)
32        } else if entry.port.listen.is_udp() {
33            PortContextKind::Udp(UdpPortContext::new(&entry)?)
34        } else if entry.port.listen.is_http() {
35            PortContextKind::Http(HttpPortContext::new(&entry)?)
36        } else {
37            PortContextKind::Tcp(TcpPortContext::new(&entry)?)
38        };
39        Ok(Self { entry, kind })
40    }
41
42    pub fn reserved() -> Self {
43        Self {
44            entry: PortEntry {
45                id: "reserved".parse().unwrap(),
46                port: Port {
47                    active: true,
48                    name: String::new(),
49                    listen: Multiaddr::default(),
50                    opts: Default::default(),
51                },
52            },
53            kind: PortContextKind::Reserved,
54        }
55    }
56
57    pub fn entry(&self) -> &PortEntry {
58        &self.entry
59    }
60
61    pub fn kind(&self) -> &PortContextKind {
62        &self.kind
63    }
64
65    pub fn kind_mut(&mut self) -> &mut PortContextKind {
66        &mut self.kind
67    }
68
69    pub async fn setup(
70        &mut self,
71        ports: &[PortEntry],
72        certs: &CertList,
73        proxies: Vec<ProxyEntry>,
74    ) -> Result<(), Error> {
75        match &mut self.kind {
76            PortContextKind::Tcp(ctx) => ctx.setup(certs, proxies).await,
77            PortContextKind::Http(ctx) => ctx.setup(ports, certs, proxies).await,
78            PortContextKind::Udp(ctx) => ctx.setup(proxies).await,
79            PortContextKind::Http3(ctx) => ctx.setup(ports, certs, proxies).await,
80            PortContextKind::Reserved => Ok(()),
81        }
82    }
83
84    pub fn apply(&mut self, new: Self) {
85        match (&mut self.kind, new.kind) {
86            (PortContextKind::Tcp(old), PortContextKind::Tcp(new)) => old.apply(new),
87            (PortContextKind::Udp(old), PortContextKind::Udp(new)) => old.apply(new),
88            (PortContextKind::Http(old), PortContextKind::Http(new)) => old.apply(new),
89            (PortContextKind::Http3(old), PortContextKind::Http3(new)) => old.apply(new),
90            (old, new) => *old = new,
91        }
92        self.entry = new.entry;
93    }
94
95    pub fn event(&mut self, event: PortContextEvent) {
96        match &mut self.kind {
97            PortContextKind::Tcp(ctx) => ctx.event(event),
98            PortContextKind::Udp(ctx) => ctx.event(event),
99            PortContextKind::Http(ctx) => ctx.event(event),
100            PortContextKind::Http3(ctx) => ctx.event(event),
101            PortContextKind::Reserved => (),
102        }
103    }
104
105    pub fn status(&self) -> &PortStatus {
106        match &self.kind {
107            PortContextKind::Tcp(ctx) => ctx.status(),
108            PortContextKind::Udp(ctx) => ctx.status(),
109            PortContextKind::Http(ctx) => ctx.status(),
110            PortContextKind::Http3(ctx) => ctx.status(),
111            PortContextKind::Reserved => {
112                static STATUS: OnceCell<PortStatus> = OnceCell::new();
113                STATUS.get_or_init(PortStatus::default)
114            }
115        }
116    }
117
118    pub fn reset(&mut self) {
119        match &mut self.kind {
120            PortContextKind::Tcp(ctx) => ctx.reset(),
121            PortContextKind::Udp(ctx) => ctx.reset(),
122            PortContextKind::Http(ctx) => ctx.reset(),
123            PortContextKind::Http3(ctx) => ctx.reset(),
124            PortContextKind::Reserved => (),
125        }
126    }
127}
128
129#[derive(Debug)]
130pub enum PortContextKind {
131    Tcp(TcpPortContext),
132    Udp(UdpPortContext),
133    Http(HttpPortContext),
134    Http3(HttpPortContext),
135    Reserved,
136}