Files
nym/clients/socks5/src/socks/server.rs
T
Jędrzej Stuczyński 596bc76cc6 Chore/dependency updates (#549)
* Updated all non-breaking dependencies

* Updated common/crypto dependencies

* Updated all tokio [and associated] dependencies to most recent version

* Bumped version of rand_distr

* Fixed api changes in tests

* Made clippy happier about the acronym

* Fixed the type while trying to make clippy even happier

* nightly cargo fmt
2021-03-29 15:32:34 +01:00

115 lines
4.1 KiB
Rust

use super::authentication::Authenticator;
use super::client::SocksClient;
use super::{
mixnet_responses::MixnetResponseListener,
types::{ResponseCode, SocksProxyError},
};
use client_core::client::{
inbound_messages::InputMessageSender, received_buffer::ReceivedBufferRequestSender,
};
use log::*;
use nymsphinx::addressing::clients::Recipient;
use proxy_helpers::connection_controller::Controller;
use std::net::SocketAddr;
use tokio::net::TcpListener;
/// A Socks5 server that listens for connections.
pub struct SphinxSocksServer {
authenticator: Authenticator,
listening_address: SocketAddr,
service_provider: Recipient,
self_address: Recipient,
}
impl SphinxSocksServer {
/// Create a new SphinxSocks instance
pub(crate) fn new(
port: u16,
authenticator: Authenticator,
service_provider: Recipient,
self_address: Recipient,
) -> Self {
// hardcode ip as we (presumably) ONLY want to listen locally. If we change it, we can
// just modify the config
let ip = "127.0.0.1";
info!("Listening on {}:{}", ip, port);
SphinxSocksServer {
authenticator,
listening_address: format!("{}:{}", ip, port).parse().unwrap(),
service_provider,
self_address,
}
}
/// Set up the listener and initiate connection handling when something
/// connects to the server.
pub(crate) async fn serve(
&mut self,
input_sender: InputMessageSender,
buffer_requester: ReceivedBufferRequestSender,
) -> Result<(), SocksProxyError> {
let listener = TcpListener::bind(self.listening_address).await.unwrap();
info!("Serving Connections...");
// controller for managing all active connections
let (mut active_streams_controller, controller_sender) = Controller::new();
tokio::spawn(async move {
active_streams_controller.run().await;
});
// listener for mix messages
let mut mixnet_response_listener =
MixnetResponseListener::new(buffer_requester, controller_sender.clone());
tokio::spawn(async move {
mixnet_response_listener.run().await;
});
loop {
if let Ok((stream, _remote)) = listener.accept().await {
// TODO Optimize this
let mut client = SocksClient::new(
stream,
self.authenticator.clone(),
input_sender.clone(),
self.service_provider,
controller_sender.clone(),
self.self_address,
);
tokio::spawn(async move {
{
match client.run().await {
Ok(_) => {}
Err(error) => {
error!("Error! {}", error);
let error_text = format!("{}", error);
let response: ResponseCode;
if error_text.contains("Host") {
response = ResponseCode::HostUnreachable;
} else if error_text.contains("Network") {
response = ResponseCode::NetworkUnreachable;
} else if error_text.contains("ttl") {
response = ResponseCode::TtlExpired
} else {
response = ResponseCode::Failure
}
if client.error(response).await.is_err() {
warn!("Failed to send error code");
};
if client.shutdown().await.is_err() {
warn!("Failed to shutdown TcpStream");
};
}
};
// client gets dropped here
}
});
}
}
}
}