Skip to main content

proxifier_rs/
lib.rs

1#![doc = include_str!("../README.md")]
2pub type Result<T> = std::result::Result<T, errors::Error>;
3
4
5#[cfg(feature = "tls")]
6pub mod tls_exports {
7    pub use rustls::{ClientConfig, RootCertStore};
8    pub use rustls_pki_types::ServerName;
9    pub use tokio::net::TcpStream;
10    pub use tokio_rustls::{TlsConnector, client::TlsStream};
11}
12
13#[cfg(feature = "tls")]
14pub use tls_exports::*;
15
16#[cfg(feature = "tls")]
17use std::sync::Arc;
18use std::{
19    borrow::Cow,
20    net::{SocketAddr, SocketAddrV4, SocketAddrV6},
21};
22fn is_ok_status(utf8_proxy_response: Cow<'_, str>) -> bool {
23    utf8_proxy_response
24        .lines()
25        .next()
26        .and_then(|line| line.split_whitespace().nth(1))
27        .and_then(|code| code.parse::<u16>().ok())
28        .map(|code| (200..399).contains(&code))
29        .unwrap_or(false)
30}
31
32pub mod auth;
33pub mod errors;
34
35pub use errors::Error;
36pub mod http;
37#[cfg(feature = "tls")]
38pub mod https;
39
40pub mod socks4;
41pub mod socks5;
42
43#[cfg(test)]
44mod tests;
45
46/// Represents either IPV4 and IPV6 via [`NetworkTarget::IP`] or domain via [`NetworkTarget::Domain`]
47#[derive(Clone)]
48pub enum NetworkTarget {
49    IP(SocketAddr),
50    Domain(String, Port),
51}
52
53/// Context contains machine level information, such as details for the proxy server and it's destination address
54pub struct Context<T = SocketAddrV4, P = SocketAddrV4> {
55    pub destination: T,
56    pub proxy: P,
57}
58
59/// Used in conjunction with [`NetworkTarget::Domain`] and in adjacency to SOCKS5 connect operations
60///
61/// # Example
62///
63/// ```rust
64///  let mut conn = crate::socks5::connect(
65///     Context {
66///         proxy: "194.113.119.68:6742".parse().unwrap(),
67///         destination: NetworkTarget::Domain("api.ipify.org".into(), Port(80)),
68///     },
69///     Auth::UserPass("vcilvnba".into(), "vi14viqvvrr7".into()),
70///  )
71///  .await?;
72/// ```
73#[repr(transparent)]
74#[derive(Clone)]
75pub struct Port(pub u16);
76
77impl From<SocketAddrV4> for NetworkTarget {
78    fn from(value: SocketAddrV4) -> Self {
79        Self::IP(SocketAddr::V4(value))
80    }
81}
82
83impl From<SocketAddrV6> for NetworkTarget {
84    fn from(value: SocketAddrV6) -> Self {
85        Self::IP(SocketAddr::V6(value))
86    }
87}
88
89/// Wraps the [`TcpStream`] so that it supports TLS
90///
91/// - `stream`: [`TcpStream`]
92/// - `config`: [`ClientConfig`]
93/// - `sni`: [`ServerName`]
94#[cfg(feature = "tls")]
95pub async fn socks_with_tls(
96    stream: TcpStream,
97    config: Arc<ClientConfig>,
98    sni: ServerName<'static>,
99) -> crate::Result<TlsStream<TcpStream>> {
100    let connector = TlsConnector::from(config);
101    let stream = connector.connect(sni, stream).await?;
102    Ok(stream)
103}