rename mixtcp -> smolmix
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
# MixTCP
|
||||
|
||||
**TODO change name to smolmix**
|
||||
|
||||
This is an initial proof of concept of a SmolTCP `device` that uses the Mixnet for transport. It relies on the `IpMixStream` module from the Rust SDK to set up a connection with an Exit Gateway's Ip-Packet-Router, meaning that this is the IP that is seen by the receiver of the request.
|
||||
|
||||
This can be used as the basis for building more generic transport crates on top of the Mixnet (e.g. trying to mirror the interface of a common HTTPS crate) whilst abstracting away the complexities of using the Mixnet for transport.
|
||||
|
||||
More to come in the future.
|
||||
|
||||
`examples/` contains examples for:
|
||||
- `cloudflare_ping` - HTTPS request to Cloudflare through the mixnet
|
||||
- `https_client` - `reqwest`-like HTTPS `GET` client with timed clearnet comparison
|
||||
- `tls` - TLS handshake diagnostics with state logging
|
||||
- `dns_udp` - DNS A-record lookup over UDP with timed clearnet comparison
|
||||
|
||||
## Component Interaction
|
||||
```sh
|
||||
create_device()
|
||||
|
|
||||
+----------+-------+-------+-----------+
|
||||
| | | |
|
||||
v v v v
|
||||
NymIprDevice NymIprBridge ShutdownHandle IpPair
|
||||
| | | (10.0.x.x)
|
||||
| | |
|
||||
+- channels + shutdown signal
|
||||
|
|
||||
v
|
||||
IpMixStream
|
||||
|
|
||||
v
|
||||
Mixnet
|
||||
```
|
||||
@@ -4,5 +4,6 @@ This repo contains several components:
|
||||
- `mixnet`: exposes Nym Client builders and methods. This is useful if you want to interact directly with the Client, or build transport abstractions.
|
||||
- `tcp_proxy`: exposes functionality to set up client/server instances that expose a localhost TcpSocket to read/write to like a 'normal' socket connection. `tcp_proxy/bin/` contains standalone `nym-proxy-client` and `nym-proxy-server` binaries.
|
||||
- `clientpool`: a configurable pool of ephemeral Nym Clients which can be created as a background process and quickly grabbed.
|
||||
- `stream_wrapper`: made up of two parts: a TCP-Socket-like abstraction (`mixnet_stream_wrapper.rs`) for a Nym Client, and an abstraction built on top of this (`mixnet_stream_wrapper_ipr`) which allows for client-side integrations to send IP packets through Exit Gateways' IpPacketRouter, and use the Mixnet as a proxy. For an example of where this is used, see the `smolmix` crate.
|
||||
|
||||
Documentation can be found [here](https://nym.com/docs/developers/rust).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "mixtcp"
|
||||
name = "smolmix"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
license.workspace = true
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
mod support;
|
||||
|
||||
use mixtcp::create_device;
|
||||
use nym_sdk::stream_wrapper::{IpMixStream, NetworkEnvironment};
|
||||
use smolmix::create_device;
|
||||
use smoltcp::{
|
||||
iface::{Config, Interface, SocketSet},
|
||||
socket::tcp,
|
||||
@@ -119,7 +119,7 @@ async fn main() -> Result<(), BoxError> {
|
||||
|
||||
// Send simple HTTP request
|
||||
request_start = tokio::time::Instant::now();
|
||||
let request = b"GET /cdn-cgi/trace HTTP/1.1\r\nHost: cloudflare.com\r\nUser-Agent: mixtcp-test/1.0\r\nAccept: */*\r\nConnection: close\r\n\r\n";
|
||||
let request = b"GET /cdn-cgi/trace HTTP/1.1\r\nHost: cloudflare.com\r\nUser-Agent: smolmix-test/1.0\r\nAccept: */*\r\nConnection: close\r\n\r\n";
|
||||
match tls_conn.send(request, socket) {
|
||||
Ok(_) => {
|
||||
info!("HTTPS request sent");
|
||||
@@ -15,8 +15,8 @@ use std::time::Duration;
|
||||
use hickory_proto::op::{Message, MessageType, OpCode, Query};
|
||||
use hickory_proto::rr::{Name, RData, RecordType};
|
||||
use hickory_resolver::TokioResolver;
|
||||
use mixtcp::create_device;
|
||||
use nym_sdk::stream_wrapper::{IpMixStream, NetworkEnvironment};
|
||||
use smolmix::create_device;
|
||||
use smoltcp::{
|
||||
iface::{Config, Interface, SocketSet},
|
||||
socket::udp,
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
mod support;
|
||||
|
||||
use mixtcp::{create_device, NymIprDevice};
|
||||
use nym_sdk::stream_wrapper::{IpMixStream, NetworkEnvironment};
|
||||
use reqwest::StatusCode;
|
||||
use smolmix::{create_device, NymIprDevice};
|
||||
use smoltcp::{
|
||||
iface::{Config, Interface, SocketSet},
|
||||
socket::tcp,
|
||||
@@ -25,14 +25,14 @@ use support::{BoxError, TlsOverTcp};
|
||||
use tracing::info;
|
||||
|
||||
/// Reqwest-ish client right now, just a handrolled GET request for the example
|
||||
pub struct MixtcpReqwestClient {
|
||||
pub struct SmolmixReqwestClient {
|
||||
device: Arc<tokio::sync::Mutex<(Interface, NymIprDevice)>>,
|
||||
bridge_handle: tokio::task::JoinHandle<()>,
|
||||
shutdown_handle: Option<mixtcp::BridgeShutdownHandle>,
|
||||
shutdown_handle: Option<smolmix::BridgeShutdownHandle>,
|
||||
_allocated_ip: Ipv4Address,
|
||||
}
|
||||
|
||||
impl MixtcpReqwestClient {
|
||||
impl SmolmixReqwestClient {
|
||||
pub async fn new() -> Result<Self, BoxError> {
|
||||
let ipr_stream = IpMixStream::new(NetworkEnvironment::Mainnet).await?;
|
||||
let (mut device, bridge, shutdown_handle, allocated_ips) =
|
||||
@@ -74,7 +74,7 @@ impl MixtcpReqwestClient {
|
||||
let _ = self.bridge_handle.await;
|
||||
}
|
||||
|
||||
pub async fn get(&self, url: &str) -> Result<MixtcpResponse, BoxError> {
|
||||
pub async fn get(&self, url: &str) -> Result<SmolmixResponse, BoxError> {
|
||||
let parsed_url = reqwest::Url::parse(url)?;
|
||||
let host = parsed_url.host_str().ok_or("URL has no host")?.to_string();
|
||||
let path = parsed_url.path().to_string();
|
||||
@@ -83,7 +83,7 @@ impl MixtcpReqwestClient {
|
||||
self.simple_get_request(&host, &path).await?;
|
||||
let (status, body) = Self::parse_simple_response(&response_bytes)?;
|
||||
|
||||
Ok(MixtcpResponse {
|
||||
Ok(SmolmixResponse {
|
||||
status,
|
||||
body,
|
||||
handshake_duration,
|
||||
@@ -159,7 +159,7 @@ impl MixtcpReqwestClient {
|
||||
|
||||
request_start = tokio::time::Instant::now();
|
||||
let request = format!(
|
||||
"GET {} HTTP/1.1\r\nHost: {}\r\nUser-Agent: mixtcp/1.0\r\nAccept: */*\r\nConnection: close\r\n\r\n",
|
||||
"GET {} HTTP/1.1\r\nHost: {}\r\nUser-Agent: smolmix/1.0\r\nAccept: */*\r\nConnection: close\r\n\r\n",
|
||||
path, domain
|
||||
);
|
||||
tls_conn.send(request.as_bytes(), socket)?;
|
||||
@@ -222,14 +222,14 @@ impl MixtcpReqwestClient {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MixtcpResponse {
|
||||
pub struct SmolmixResponse {
|
||||
status: u16,
|
||||
body: String,
|
||||
handshake_duration: Duration,
|
||||
request_duration: Duration,
|
||||
}
|
||||
|
||||
impl MixtcpResponse {
|
||||
impl SmolmixResponse {
|
||||
pub fn status(&self) -> StatusCode {
|
||||
StatusCode::from_u16(self.status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
@@ -258,7 +258,7 @@ async fn main() -> Result<(), BoxError> {
|
||||
);
|
||||
|
||||
info!("Setting up mixnet client...");
|
||||
let client = MixtcpReqwestClient::new().await?;
|
||||
let client = SmolmixReqwestClient::new().await?;
|
||||
let mixnet_response = client.get(test_url).await?;
|
||||
let mixnet_status = mixnet_response.status();
|
||||
let handshake_duration = mixnet_response.handshake_duration;
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
//! Shared helpers for the TCP/TLS mixtcp examples.
|
||||
//! Shared helpers for the TCP/TLS smolmix examples.
|
||||
//!
|
||||
//! Provides a [`TlsOverTcp`] adapter that bridges rustls with smoltcp TCP
|
||||
//! sockets, plus common utilities like [`init_logging`].
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
mod support;
|
||||
|
||||
use mixtcp::create_device;
|
||||
use nym_sdk::stream_wrapper::{IpMixStream, NetworkEnvironment};
|
||||
use smolmix::create_device;
|
||||
use smoltcp::{
|
||||
iface::{Config, Interface, SocketSet},
|
||||
socket::tcp,
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
use crate::error::MixtcpError;
|
||||
use crate::error::SmolmixError;
|
||||
use nym_ip_packet_requests::codec::MultiIpPacketCodec;
|
||||
use nym_sdk::stream_wrapper::IpMixStream;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
@@ -75,7 +75,7 @@ impl NymIprBridge {
|
||||
///
|
||||
/// The loop exits when a shutdown signal is received, channels are closed,
|
||||
/// or an error occurs. On exit the mixnet client is disconnected gracefully.
|
||||
pub async fn run(mut self) -> Result<(), MixtcpError> {
|
||||
pub async fn run(mut self) -> Result<(), SmolmixError> {
|
||||
info!("Starting Nym IPR bridge");
|
||||
let mut packets_sent = 0;
|
||||
let mut packets_received = 0;
|
||||
@@ -115,7 +115,7 @@ impl NymIprBridge {
|
||||
// Forward to device via channel
|
||||
if self.rx_sender.send(packet.to_vec()).is_err() {
|
||||
error!("Failed to send packet to device - receiver dropped");
|
||||
return Err(MixtcpError::ChannelClosed);
|
||||
return Err(SmolmixError::ChannelClosed);
|
||||
}
|
||||
packets_received += 1;
|
||||
debug!("Total packets received: {}", packets_received);
|
||||
@@ -4,7 +4,7 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MixtcpError {
|
||||
pub enum SmolmixError {
|
||||
#[error("Channel closed")]
|
||||
ChannelClosed,
|
||||
|
||||
@@ -7,7 +7,7 @@ mod error;
|
||||
|
||||
pub use bridge::{BridgeShutdownHandle, NymIprBridge};
|
||||
pub use device::NymIprDevice;
|
||||
pub use error::MixtcpError;
|
||||
pub use error::SmolmixError;
|
||||
|
||||
use nym_ip_packet_requests::IpPair;
|
||||
use nym_sdk::stream_wrapper::IpMixStream;
|
||||
@@ -27,7 +27,7 @@ use tokio::sync::mpsc;
|
||||
/// to disconnect from the mixnet cleanly.
|
||||
pub async fn create_device(
|
||||
mut ipr_stream: IpMixStream,
|
||||
) -> Result<(NymIprDevice, NymIprBridge, BridgeShutdownHandle, IpPair), MixtcpError> {
|
||||
) -> Result<(NymIprDevice, NymIprBridge, BridgeShutdownHandle, IpPair), SmolmixError> {
|
||||
// Ensure the stream is connected
|
||||
if !ipr_stream.is_connected() {
|
||||
ipr_stream.connect_tunnel().await?;
|
||||
@@ -37,7 +37,7 @@ pub async fn create_device(
|
||||
// further 'up' the flow in the code calling this fn.
|
||||
let allocated_ips = *ipr_stream
|
||||
.allocated_ips()
|
||||
.ok_or(MixtcpError::NotConnected)?;
|
||||
.ok_or(SmolmixError::NotConnected)?;
|
||||
|
||||
// Create channels for device <-> bridge communication
|
||||
let (tx_to_bridge, tx_from_device) = mpsc::unbounded_channel();
|
||||
Reference in New Issue
Block a user