raknet-rust 0.2.0

Asynchronous, high-performance RakNet transport library for Rust.
Documentation
use std::net::SocketAddr;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InboundProxyRoute {
    Local { session_addr: SocketAddr },
    Drop,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OutboundProxyRoute {
    Send { target_addr: SocketAddr },
    Drop,
}

pub trait ProxyRouter: Send + Sync + 'static {
    fn route_inbound(
        &self,
        observed_src: SocketAddr,
        _local_addr: SocketAddr,
    ) -> InboundProxyRoute {
        InboundProxyRoute::Local {
            session_addr: observed_src,
        }
    }

    fn route_outbound(
        &self,
        session_addr: SocketAddr,
        _local_addr: SocketAddr,
    ) -> OutboundProxyRoute {
        OutboundProxyRoute::Send {
            target_addr: session_addr,
        }
    }
}

#[derive(Debug, Clone, Copy, Default)]
pub struct IdentityProxyRouter;

impl ProxyRouter for IdentityProxyRouter {}

#[cfg(test)]
mod tests {
    use std::net::SocketAddr;

    use super::{IdentityProxyRouter, InboundProxyRoute, OutboundProxyRoute, ProxyRouter};

    struct CustomProxyRouter {
        inbound: InboundProxyRoute,
        outbound: OutboundProxyRoute,
    }

    impl ProxyRouter for CustomProxyRouter {
        fn route_inbound(
            &self,
            _observed_src: SocketAddr,
            _local_addr: SocketAddr,
        ) -> InboundProxyRoute {
            self.inbound
        }

        fn route_outbound(
            &self,
            _session_addr: SocketAddr,
            _local_addr: SocketAddr,
        ) -> OutboundProxyRoute {
            self.outbound
        }
    }

    struct DefaultTraitRouter;

    impl ProxyRouter for DefaultTraitRouter {}

    #[test]
    fn identity_router_keeps_addresses_unchanged() {
        let router = IdentityProxyRouter;
        let src = "127.0.0.1:19132"
            .parse::<SocketAddr>()
            .expect("valid socket addr");
        let local = "0.0.0.0:19132"
            .parse::<SocketAddr>()
            .expect("valid socket addr");

        assert_eq!(
            router.route_inbound(src, local),
            InboundProxyRoute::Local { session_addr: src }
        );
        assert_eq!(
            router.route_outbound(src, local),
            OutboundProxyRoute::Send { target_addr: src }
        );
    }

    #[test]
    fn custom_router_can_reroute_inbound_and_drop_outbound() {
        let rerouted = "10.0.0.9:20000"
            .parse::<SocketAddr>()
            .expect("valid socket addr");
        let router = CustomProxyRouter {
            inbound: InboundProxyRoute::Local {
                session_addr: rerouted,
            },
            outbound: OutboundProxyRoute::Drop,
        };
        let src = "127.0.0.1:19132"
            .parse::<SocketAddr>()
            .expect("valid socket addr");
        let local = "0.0.0.0:19132"
            .parse::<SocketAddr>()
            .expect("valid socket addr");

        assert_eq!(
            router.route_inbound(src, local),
            InboundProxyRoute::Local {
                session_addr: rerouted
            }
        );
        assert_eq!(router.route_outbound(src, local), OutboundProxyRoute::Drop);
    }

    #[test]
    fn trait_default_methods_behave_like_identity_router() {
        let router = DefaultTraitRouter;
        let src = "192.168.1.50:19132"
            .parse::<SocketAddr>()
            .expect("valid socket addr");
        let local = "0.0.0.0:19132"
            .parse::<SocketAddr>()
            .expect("valid socket addr");

        assert_eq!(
            router.route_inbound(src, local),
            InboundProxyRoute::Local { session_addr: src }
        );
        assert_eq!(
            router.route_outbound(src, local),
            OutboundProxyRoute::Send { target_addr: src }
        );
    }
}