pub async fn read_address<T: AsyncRead + Unpin>(
    stream: &mut T,
    atyp: u8,
) -> anyhow::Result<TargetAddr> {
    let addr = match atyp {
        consts::SOCKS5_ADDR_TYPE_IPV4 => {
            debug!("Address type `IPv4`");
            Addr::V4(read_exact!(stream, [0u8; 4]).context(AddrError::IPv4Unreadable)?)
        }
        consts::SOCKS5_ADDR_TYPE_IPV6 => {
            debug!("Address type `IPv6`");
            Addr::V6(read_exact!(stream, [0u8; 16]).context(AddrError::IPv6Unreadable)?)
        }
        consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME => {
            debug!("Address type `domain`");
            let len = read_exact!(stream, [0]).context(AddrError::DomainLenUnreadable)?[0];
            let domain = read_exact!(stream, vec![0u8; len as usize])
                .context(AddrError::DomainContentUnreadable)?;
            // make sure the bytes are correct utf8 string
            let domain = String::from_utf8(domain).context(AddrError::Utf8)?;

            Addr::Domain(domain)
        }
        _ => return Err(anyhow::anyhow!(AddrError::IncorrectAddressType)),
    };

    // Find port number
    let port = read_exact!(stream, [0u8; 2]).context(AddrError::PortNumberUnreadable)?;
    // Convert (u8 * 2) into u16
    let port = (port[0] as u16) << 8 | port[1] as u16;

    // Merge ADDRESS + PORT into a TargetAddr
    let addr: TargetAddr = match addr {
        Addr::V4([a, b, c, d]) => (Ipv4Addr::new(a, b, c, d), port).to_target_addr()?,
        Addr::V6(x) => (Ipv6Addr::from(x), port).to_target_addr()?,
        Addr::Domain(domain) => TargetAddr::Domain(domain, port),
    };

    Ok(addr)
}
/// This function is used by the client & the server
This function is used by the client & the server
This function is used by the client & the server
pub async fn read_address<T: AsyncRead + Unpin>(
    stream: &mut T,
    atyp: u8,
) -> anyhow::Result<TargetAddr> {
    let addr = match atyp {
        consts::SOCKS5_ADDR_TYPE_IPV4 => {
            debug!("Address type `IPv4`");
            Addr::V4(read_exact!(stream, [0u8; 4]).context(AddrError::IPv4Unreadable)?)
        }
        consts::SOCKS5_ADDR_TYPE_IPV6 => {
            debug!("Address type `IPv6`");
            Addr::V6(read_exact!(stream, [0u8; 16]).context(AddrError::IPv6Unreadable)?)
        }
        consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME => {
            debug!("Address type `domain`");
            let len = read_exact!(stream, [0]).context(AddrError::DomainLenUnreadable)?[0];
            let domain = read_exact!(stream, vec![0u8; len as usize])
                .context(AddrError::DomainContentUnreadable)?;
            // make sure the bytes are correct utf8 string
            let domain = String::from_utf8(domain).context(AddrError::Utf8)?;
            Addr::Domain(domain)
        }
        _ => return Err(anyhow::anyhow!(AddrError::IncorrectAddressType)),
    };
    // Find port number
    let port = read_exact!(stream, [0u8; 2]).context(AddrError::PortNumberUnreadable)?;
    // Convert (u8 * 2) into u16
    let port = (port[0] as u16) << 8 | port[1] as u16;
    // Merge ADDRESS + PORT into a TargetAddr
    let addr: TargetAddr = match addr {
        Addr::V4([a, b, c, d]) => (Ipv4Addr::new(a, b, c, d), port).to_target_addr()?,
        Addr::V6(x) => (Ipv6Addr::from(x), port).to_target_addr()?,
        Addr::Domain(domain) => TargetAddr::Domain(domain, port),
    };
    Ok(addr)
}
pub async fn read_address < T : AsyncRead + Unpin > ( stream : & mut T , atyp : u8 , ) -> anyhow :: Result < TargetAddr > { let addr = match atyp { consts :: SOCKS5_ADDR_TYPE_IPV4 => { debug ! ( " " ) ; Addr :: V4 ( read_exact ! ( stream [ 0u8 4 ] ) . context ( AddrError :: IPv4Unreadable ) ? ) } consts :: SOCKS5_ADDR_TYPE_IPV6 => { debug ! ( " " ) ; Addr :: V6 ( read_exact ! ( stream [ 0u8 16 ] ) . context ( AddrError :: IPv6Unreadable ) ? ) } consts :: SOCKS5_ADDR_TYPE_DOMAIN_NAME => { debug ! ( " " ) ; let len = read_exact ! ( stream [ 0 ] ) . context ( AddrError :: DomainLenUnreadable ) ? [ 0 ] ; let domain = read_exact ! ( stream vec [ 0u8 len as usize ] ) . context ( AddrError :: DomainContentUnreadable ) ? ; // make sure the bytes are correct utf8 string let domain = String :: from_utf8 ( domain ) . context ( AddrError :: Utf8 ) ? ; Addr :: Domain ( domain ) } _ => return Err ( anyhow :: anyhow ! ( AddrError IncorrectAddressType ) ) , } ; // Find port number let port = read_exact ! ( stream [ 0u8 2 ] ) . context ( AddrError :: PortNumberUnreadable ) ? ; // Convert (u8 * 2) into u16 let port = ( port [ 0 ] as u16 ) << 8 | port [ 1 ] as u16 ; // Merge ADDRESS + PORT into a TargetAddr let addr : TargetAddr = match addr { Addr :: V4 ( [ a , b , c , d ] ) => ( Ipv4Addr :: new ( a , b , c , d ) , port ) . to_target_addr ( ) ? , Addr :: V6 ( x ) => ( Ipv6Addr :: from ( x ) , port ) . to_target_addr ( ) ? , Addr :: Domain ( domain ) => TargetAddr :: Domain ( domain , port ) , } ; Ok ( addr ) }
This function is used by the client & the server
This function is used by the client & the server
stream
&mut T
atyp
u8
stream
&mut T
atyp
u8