UDP Associate

This commit is contained in:
ssrlive 2023-08-10 12:57:35 +08:00
parent 382c2ac6e3
commit 94835c41a4
3 changed files with 30 additions and 10 deletions

View file

@ -1,5 +1,5 @@
use crate::{
error::Error,
error::{Error, Result},
tun2proxy::{
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, OutgoingDataEvent,
OutgoingDirection, TcpProxy,
@ -7,7 +7,7 @@ use crate::{
};
use smoltcp::wire::IpProtocol;
use socks5_impl::protocol::{self, handshake, password_method, Address, AuthMethod, StreamOperation, UserKey, Version};
use std::{collections::VecDeque, net::SocketAddr};
use std::{collections::VecDeque, convert::TryFrom, net::SocketAddr};
#[derive(Eq, PartialEq, Debug)]
#[allow(dead_code)]
@ -31,10 +31,17 @@ struct SocksProxyImpl {
data_buf: VecDeque<u8>,
version: Version,
credentials: Option<UserKey>,
command: protocol::Command,
udp_associate: Option<SocketAddr>,
}
impl SocksProxyImpl {
fn new(info: &ConnectionInfo, credentials: Option<UserKey>, version: Version) -> Result<Self, Error> {
fn new(
info: &ConnectionInfo,
credentials: Option<UserKey>,
version: Version,
command: protocol::Command,
) -> Result<Self> {
let mut result = Self {
info: info.clone(),
state: SocksState::ServerHello,
@ -45,6 +52,8 @@ impl SocksProxyImpl {
data_buf: VecDeque::default(),
version,
credentials,
command,
udp_associate: None,
};
result.send_client_hello()?;
Ok(result)
@ -195,8 +204,7 @@ impl SocksProxyImpl {
}
fn send_request_socks5(&mut self) -> Result<(), Error> {
protocol::Request::new(protocol::Command::Connect, self.info.dst.clone())
.write_to_stream(&mut self.server_outbuf)?;
protocol::Request::new(self.command, self.info.dst.clone()).write_to_stream(&mut self.server_outbuf)?;
self.state = SocksState::ReceiveResponse;
self.state_change()
}
@ -216,6 +224,9 @@ impl SocksProxyImpl {
if response.reply != protocol::Reply::Succeeded {
return Err(format!("SOCKS connection failed: {}", response.reply).into());
}
if self.command == protocol::Command::UdpAssociate {
self.udp_associate = Some(SocketAddr::try_from(response.address)?);
}
self.server_outbuf.append(&mut self.data_buf);
self.data_buf.clear();
@ -325,14 +336,17 @@ impl ConnectionManager for SocksProxyManager {
info.protocol == IpProtocol::Tcp
}
fn new_tcp_proxy(&self, info: &ConnectionInfo) -> Result<Box<dyn TcpProxy>, Error> {
fn new_tcp_proxy(&self, info: &ConnectionInfo, udp_associate: bool) -> Result<Box<dyn TcpProxy>> {
if info.protocol != IpProtocol::Tcp {
return Err("Invalid protocol".into());
}
use socks5_impl::protocol::Command::{Connect, UdpAssociate};
let command = if udp_associate { UdpAssociate } else { Connect };
Ok(Box::new(SocksProxyImpl::new(
info,
self.credentials.clone(),
self.version,
command,
)?))
}