Skip to main content

raknet_rust/transport/
proxy.rs

1use std::net::SocketAddr;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum InboundProxyRoute {
5    Local { session_addr: SocketAddr },
6    Drop,
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum OutboundProxyRoute {
11    Send { target_addr: SocketAddr },
12    Drop,
13}
14
15pub trait ProxyRouter: Send + Sync + 'static {
16    fn route_inbound(
17        &self,
18        observed_src: SocketAddr,
19        _local_addr: SocketAddr,
20    ) -> InboundProxyRoute {
21        InboundProxyRoute::Local {
22            session_addr: observed_src,
23        }
24    }
25
26    fn route_outbound(
27        &self,
28        session_addr: SocketAddr,
29        _local_addr: SocketAddr,
30    ) -> OutboundProxyRoute {
31        OutboundProxyRoute::Send {
32            target_addr: session_addr,
33        }
34    }
35}
36
37#[derive(Debug, Clone, Copy, Default)]
38pub struct IdentityProxyRouter;
39
40impl ProxyRouter for IdentityProxyRouter {}
41
42#[cfg(test)]
43mod tests {
44    use std::net::SocketAddr;
45
46    use super::{IdentityProxyRouter, InboundProxyRoute, OutboundProxyRoute, ProxyRouter};
47
48    struct CustomProxyRouter {
49        inbound: InboundProxyRoute,
50        outbound: OutboundProxyRoute,
51    }
52
53    impl ProxyRouter for CustomProxyRouter {
54        fn route_inbound(
55            &self,
56            _observed_src: SocketAddr,
57            _local_addr: SocketAddr,
58        ) -> InboundProxyRoute {
59            self.inbound
60        }
61
62        fn route_outbound(
63            &self,
64            _session_addr: SocketAddr,
65            _local_addr: SocketAddr,
66        ) -> OutboundProxyRoute {
67            self.outbound
68        }
69    }
70
71    struct DefaultTraitRouter;
72
73    impl ProxyRouter for DefaultTraitRouter {}
74
75    #[test]
76    fn identity_router_keeps_addresses_unchanged() {
77        let router = IdentityProxyRouter;
78        let src = "127.0.0.1:19132"
79            .parse::<SocketAddr>()
80            .expect("valid socket addr");
81        let local = "0.0.0.0:19132"
82            .parse::<SocketAddr>()
83            .expect("valid socket addr");
84
85        assert_eq!(
86            router.route_inbound(src, local),
87            InboundProxyRoute::Local { session_addr: src }
88        );
89        assert_eq!(
90            router.route_outbound(src, local),
91            OutboundProxyRoute::Send { target_addr: src }
92        );
93    }
94
95    #[test]
96    fn custom_router_can_reroute_inbound_and_drop_outbound() {
97        let rerouted = "10.0.0.9:20000"
98            .parse::<SocketAddr>()
99            .expect("valid socket addr");
100        let router = CustomProxyRouter {
101            inbound: InboundProxyRoute::Local {
102                session_addr: rerouted,
103            },
104            outbound: OutboundProxyRoute::Drop,
105        };
106        let src = "127.0.0.1:19132"
107            .parse::<SocketAddr>()
108            .expect("valid socket addr");
109        let local = "0.0.0.0:19132"
110            .parse::<SocketAddr>()
111            .expect("valid socket addr");
112
113        assert_eq!(
114            router.route_inbound(src, local),
115            InboundProxyRoute::Local {
116                session_addr: rerouted
117            }
118        );
119        assert_eq!(router.route_outbound(src, local), OutboundProxyRoute::Drop);
120    }
121
122    #[test]
123    fn trait_default_methods_behave_like_identity_router() {
124        let router = DefaultTraitRouter;
125        let src = "192.168.1.50:19132"
126            .parse::<SocketAddr>()
127            .expect("valid socket addr");
128        let local = "0.0.0.0:19132"
129            .parse::<SocketAddr>()
130            .expect("valid socket addr");
131
132        assert_eq!(
133            router.route_inbound(src, local),
134            InboundProxyRoute::Local { session_addr: src }
135        );
136        assert_eq!(
137            router.route_outbound(src, local),
138            OutboundProxyRoute::Send { target_addr: src }
139        );
140    }
141}