diff --git a/Cargo.lock b/Cargo.lock index c59fc2aced5..55166e6b80b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1123,6 +1123,17 @@ dependencies = [ "serde", ] +[[package]] +name = "iptables" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c488ad8e743814579544d5a17bda107cd7a4009ade4d55ce94f4c3ec0281147" +dependencies = [ + "lazy_static", + "nix 0.23.1", + "regex", +] + [[package]] name = "itertools" version = "0.10.3" @@ -1460,11 +1471,14 @@ dependencies = [ "dns-lookup", "faccess", "futures", + "iptables", + "libc", "mirrord-protocol", - "nix", + "nix 0.24.2", "num-traits", "pcap", "pnet", + "rand 0.8.5", "serde", "serde_json", "streammap-ext", @@ -1495,6 +1509,7 @@ name = "mirrord-layer" version = "2.10.1" dependencies = [ "actix-codec", + "anyhow", "async-trait", "bytes", "ctor", @@ -1508,15 +1523,17 @@ dependencies = [ "libc", "mirrord-macro", "mirrord-protocol", - "nix", + "nix 0.24.2", "rand 0.8.5", "regex", "serde_json", "socket2", "stacker", + "streammap-ext", "thiserror", "tokio", "tokio-stream", + "tokio-util 0.7.3", "tracing", "tracing-subscriber", ] @@ -1621,6 +1638,19 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "nix" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "nix" version = "0.24.2" @@ -2666,9 +2696,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10c98bba371b9b22a71a9414e420f92ddeb2369239af08200816169d5e2dd7aa" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -2779,6 +2809,7 @@ checksum = "8e7a7de15468c6e65dd7db81cf3822c1ec94c71b2a3c1a976ea8e4696c91115c" name = "tests" version = "0.1.0" dependencies = [ + "bytes", "chrono", "futures", "futures-util", diff --git a/Cargo.toml b/Cargo.toml index c2134477808..f74cbc0a951 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,10 @@ k8s-openapi = { version = "0.15", features = ["v1_24"] } reqwest = { version = "0.11", features = ["blocking"] } kube = { version = "0.73", default-features = false, features = ["runtime", "derive", "client", "ws", "rustls-tls"] } dns-lookup = "1" +tokio-util = "0.7" +rand = "0.8" +streammap-ext = "0.1" + # latest commits on rustls suppress certificate verification # https://github.com/rustls/rustls/pull/1032 diff --git a/mirrord-agent/Cargo.toml b/mirrord-agent/Cargo.toml index 08195cf8d92..81c3504707b 100644 --- a/mirrord-agent/Cargo.toml +++ b/mirrord-agent/Cargo.toml @@ -33,9 +33,12 @@ thiserror.workspace = true dns-lookup.workspace = true num-traits = "0.2" bollard = "0.13" -tokio-util = "0.7" +tokio-util.workspace = true +rand.workspace = true +streammap-ext.workspace = true +iptables = "0.5" +libc = "0.2" faccess = "0.2" -streammap-ext = "0.1" [dev-dependencies] test_bin = "0.4" \ No newline at end of file diff --git a/mirrord-agent/Dockerfile b/mirrord-agent/Dockerfile index 2cedcaae977..21483771c2f 100644 --- a/mirrord-agent/Dockerfile +++ b/mirrord-agent/Dockerfile @@ -14,7 +14,9 @@ COPY .cargo /app/.cargo RUN cargo +nightly build -Z bindeps --manifest-path /app/mirrord-agent/Cargo.toml --release FROM debian:stable -RUN apt update && apt install -y libpcap-dev COPY --from=build-env /app/target/release/mirrord-agent / +RUN apt update && apt install -y libpcap-dev iptables +RUN update-alternatives --set iptables /usr/sbin/iptables-legacy \ + && update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy CMD ["./mirrord-agent"] \ No newline at end of file diff --git a/mirrord-agent/src/error.rs b/mirrord-agent/src/error.rs index 0ee54c47a2f..78d86626c74 100644 --- a/mirrord-agent/src/error.rs +++ b/mirrord-agent/src/error.rs @@ -1,9 +1,9 @@ use mirrord_protocol::{ tcp::{ outgoing::{DaemonTcpOutgoing, LayerConnect, LayerTcpOutgoing}, - DaemonTcp, + DaemonTcp, LayerTcpSteal, }, - FileRequest, FileResponse, + FileRequest, FileResponse, Port, }; use thiserror::Error; @@ -68,6 +68,17 @@ pub enum AgentError { #[error("Bollard failed with `{0}`")] Bollard(#[from] bollard::errors::Error), + #[error("Connection received from unexepcted port `{0}`")] + UnexpectedConnection(Port), + + #[error("LayerTcpSteal sender failed with `{0}`")] + SendLayerTcpSteal(#[from] tokio::sync::mpsc::error::SendError), + + #[error("IPTables failed with `{0}`")] + IPTablesError(String), + #[error("Join task failed")] JoinTask, } + +pub type Result = std::result::Result; diff --git a/mirrord-agent/src/main.rs b/mirrord-agent/src/main.rs index f022df63f42..dc7e57cb0df 100644 --- a/mirrord-agent/src/main.rs +++ b/mirrord-agent/src/main.rs @@ -16,8 +16,9 @@ use futures::{ SinkExt, }; use mirrord_protocol::{ - tcp::LayerTcp, AddrInfoHint, AddrInfoInternal, ClientMessage, DaemonCodec, DaemonMessage, - GetAddrInfoRequest, GetEnvVarsRequest, RemoteResult, ResponseError, + tcp::{DaemonTcp, LayerTcp, LayerTcpSteal}, + AddrInfoHint, AddrInfoInternal, ClientMessage, DaemonCodec, DaemonMessage, GetAddrInfoRequest, + GetEnvVarsRequest, RemoteResult, ResponseError, }; use sniffer::{SnifferCommand, TCPConnectionSniffer, TCPSnifferAPI}; use tcp::outgoing::TcpOutgoingApi; @@ -25,20 +26,24 @@ use tokio::{ io::AsyncReadExt, net::{TcpListener, TcpStream}, select, - sync::mpsc::{self, Sender}, + sync::mpsc::{self, Receiver, Sender}, }; use tokio_util::sync::CancellationToken; use tracing::{debug, error, info, trace}; use tracing_subscriber::prelude::*; -use util::{ClientID, IndexAllocator}; -use crate::{runtime::get_container_pid, util::run_thread}; +use crate::{ + runtime::get_container_pid, + steal::steal_worker, + util::{run_thread, ClientID, IndexAllocator}, +}; mod cli; mod error; mod file; mod runtime; mod sniffer; +mod steal; mod tcp; mod util; @@ -178,6 +183,8 @@ struct ClientConnectionHandler { stream: Framed, pid: Option, tcp_sniffer_api: TCPSnifferAPI, + tcp_stealer_sender: Sender, + tcp_stealer_receiver: Receiver, tcp_outgoing_api: TcpOutgoingApi, } @@ -201,6 +208,14 @@ impl ClientConnectionHandler { let (tcp_sender, tcp_receiver) = mpsc::channel(CHANNEL_SIZE); let tcp_sniffer_api = TCPSnifferAPI::new(id, sniffer_command_sender, tcp_receiver, tcp_sender).await?; + let (tcp_steal_layer_sender, tcp_steal_layer_receiver) = mpsc::channel(CHANNEL_SIZE); + let (tcp_steal_daemon_sender, tcp_steal_daemon_receiver) = mpsc::channel(CHANNEL_SIZE); + + let _ = run_thread(steal_worker( + tcp_steal_layer_receiver, + tcp_steal_daemon_sender, + pid, + )); let tcp_outgoing_api = TcpOutgoingApi::new(pid); @@ -210,11 +225,12 @@ impl ClientConnectionHandler { stream, pid, tcp_sniffer_api, + tcp_stealer_receiver: tcp_steal_daemon_receiver, + tcp_stealer_sender: tcp_steal_layer_sender, tcp_outgoing_api, }; client_handler.handle_loop(cancel_token).await?; - Ok(()) } @@ -243,10 +259,18 @@ impl ClientConnectionHandler { error!("tcp sniffer stopped?"); break; } - } + }, + message = self.tcp_stealer_receiver.recv() => { + if let Some(message) = message { + self.stream.send(DaemonMessage::TcpSteal(message)).await?; + } else { + error!("tcp stealer stopped?"); + break; + } + }, message = self.tcp_outgoing_api.daemon_message() => { self.respond(DaemonMessage::TcpOutgoing(message?)).await?; - } + }, _ = token.cancelled() => { break; } @@ -298,6 +322,7 @@ impl ClientConnectionHandler { } ClientMessage::Ping => self.respond(DaemonMessage::Pong).await?, ClientMessage::Tcp(message) => self.handle_client_tcp(message).await?, + ClientMessage::TcpSteal(message) => self.tcp_stealer_sender.send(message).await?, ClientMessage::Close => { return Ok(false); } diff --git a/mirrord-agent/src/steal.rs b/mirrord-agent/src/steal.rs new file mode 100644 index 00000000000..14355e22a65 --- /dev/null +++ b/mirrord-agent/src/steal.rs @@ -0,0 +1,409 @@ +use std::{ + collections::{HashMap, HashSet}, + net::SocketAddr, + path::PathBuf, +}; + +use mirrord_protocol::{ + tcp::{DaemonTcp, LayerTcpSteal, NewTcpConnection, TcpClose, TcpData}, + ConnectionId, Port, +}; +use rand::distributions::{Alphanumeric, DistString}; +use streammap_ext::StreamMap; +use tokio::{ + io::{AsyncWriteExt, ReadHalf, WriteHalf}, + net::{TcpListener, TcpStream}, + select, + sync::mpsc::{Receiver, Sender}, +}; +use tokio_stream::StreamExt; +use tokio_util::io::ReaderStream; +use tracing::{debug, error, info, log::warn}; + +use crate::{ + error::{AgentError, Result}, + runtime::set_namespace, +}; + +/// Wrapper struct for IPTables so it flushes on drop. +struct SafeIpTables { + inner: iptables::IPTables, + chain_name: String, +} + +const IPTABLES_TABLE_NAME: &str = "nat"; + +fn format_redirect_rule(redirected_port: Port, target_port: Port) -> String { + format!( + "-p tcp -m tcp --dport {} -j REDIRECT --to-ports {}", + redirected_port, target_port + ) +} + +/// Wrapper for using iptables. This creates a a new chain on creation and deletes it on drop. +/// The way it works is that it adds a chain, then adds a rule to the chain that returns to the +/// original chain (fallback) and adds a rule in the "PREROUTING" table that jumps to the new chain. +/// Connections will go then PREROUTING -> OUR_CHAIN -> IF MATCH REDIRECT -> IF NOT MATCH FALLBACK +/// -> ORIGINAL_CHAIN +impl SafeIpTables { + pub fn new() -> Result { + let ipt = iptables::new(false).unwrap(); + let random_string = Alphanumeric.sample_string(&mut rand::thread_rng(), 5); + let chain_name = format!("MIRRORD_REDIRECT_{}", random_string); + ipt.new_chain(IPTABLES_TABLE_NAME, &chain_name) + .map_err(|e| AgentError::IPTablesError(e.to_string()))?; + ipt.append(IPTABLES_TABLE_NAME, &chain_name, "-j RETURN") + .map_err(|e| AgentError::IPTablesError(e.to_string()))?; + ipt.append( + IPTABLES_TABLE_NAME, + "PREROUTING", + &format!("-j {}", chain_name), + ) + .map_err(|e| AgentError::IPTablesError(e.to_string()))?; + Ok(Self { + inner: ipt, + chain_name, + }) + } + + pub fn add_redirect(&mut self, redirected_port: Port, target_port: Port) -> Result<()> { + self.inner + .insert( + IPTABLES_TABLE_NAME, + &self.chain_name, + &format_redirect_rule(redirected_port, target_port), + 1, + ) + .map_err(|e| AgentError::IPTablesError(e.to_string())) + } + + pub fn remove_redirect(&mut self, redirected_port: Port, target_port: Port) -> Result<()> { + self.inner + .delete( + IPTABLES_TABLE_NAME, + &self.chain_name, + &format_redirect_rule(redirected_port, target_port), + ) + .map_err(|e| AgentError::IPTablesError(e.to_string())) + } +} + +impl Drop for SafeIpTables { + fn drop(&mut self) { + self.inner + .delete( + IPTABLES_TABLE_NAME, + "PREROUTING", + &format!("-j {}", self.chain_name), + ) + .unwrap(); + self.inner + .flush_chain(IPTABLES_TABLE_NAME, &self.chain_name) + .unwrap(); + self.inner + .delete_chain(IPTABLES_TABLE_NAME, &self.chain_name) + .unwrap(); + } +} + +pub struct StealWorker { + pub sender: Sender, + iptables: SafeIpTables, + ports: HashSet, + listen_port: Port, + write_streams: HashMap>, + read_streams: StreamMap>>, + connection_index: u64, +} + +impl StealWorker { + pub fn new(sender: Sender, listen_port: Port) -> Result { + Ok(Self { + sender, + iptables: SafeIpTables::new()?, + ports: HashSet::default(), + listen_port, + write_streams: HashMap::default(), + read_streams: StreamMap::default(), + connection_index: 0, + }) + } + + pub async fn handle_loop( + &mut self, + mut rx: Receiver, + listener: TcpListener, + ) -> Result<()> { + loop { + select! { + msg = rx.recv() => { + if let Some(msg) = msg { + self.handle_client_message(msg).await?; + } else { + debug!("rx closed, breaking"); + break; + } + }, + accept = listener.accept() => { + match accept { + Ok((stream, address)) => { + self.handle_incoming_connection(stream, address).await?; + }, + Err(err) => { + error!("accept error {err:?}"); + break; + } + } + }, + message = self.next() => { + if let Some(message) = message { + self.sender.send(message).await?; + } + } + } + } + debug!("TCP Stealer exiting"); + Ok(()) + } + + pub async fn handle_client_message(&mut self, message: LayerTcpSteal) -> Result<()> { + use LayerTcpSteal::*; + match message { + PortSubscribe(port) => { + if self.ports.contains(&port) { + warn!("Port {port:?} is already subscribed"); + Ok(()) + } else { + debug!("adding redirect rule"); + self.iptables.add_redirect(port, self.listen_port)?; + self.ports.insert(port); + self.sender.send(DaemonTcp::Subscribed).await?; + debug!("sent subscribed"); + Ok(()) + } + } + ConnectionUnsubscribe(connection_id) => { + info!("Closing connection {connection_id:?}"); + self.write_streams.remove(&connection_id); + self.read_streams.remove(&connection_id); + Ok(()) + } + PortUnsubscribe(port) => { + if self.ports.remove(&port) { + self.iptables.remove_redirect(port, self.listen_port) + } else { + warn!("removing unsubscribed port {port:?}"); + Ok(()) + } + } + + Data(data) => { + if let Some(stream) = self.write_streams.get_mut(&data.connection_id) { + stream.write_all(&data.bytes[..]).await?; + Ok(()) + } else { + warn!( + "Trying to send data to closed connection {:?}", + data.connection_id + ); + Ok(()) + } + } + } + } + + pub async fn handle_incoming_connection( + &mut self, + stream: TcpStream, + address: SocketAddr, + ) -> Result<()> { + let real_addr = orig_dst::orig_dst_addr(&stream)?; + if !self.ports.contains(&real_addr.port()) { + return Err(AgentError::UnexpectedConnection(real_addr.port())); + } + let connection_id = self.connection_index; + self.connection_index += 1; + + let (read_half, write_half) = tokio::io::split(stream); + self.write_streams.insert(connection_id, write_half); + self.read_streams + .insert(connection_id, ReaderStream::new(read_half)); + + let new_connection = DaemonTcp::NewConnection(NewTcpConnection { + connection_id, + destination_port: real_addr.port(), + source_port: address.port(), + address: address.ip(), + }); + self.sender.send(new_connection).await?; + debug!("sent new connection"); + Ok(()) + } + + pub async fn next(&mut self) -> Option { + let (connection_id, value) = self.read_streams.next().await?; + match value { + Some(Ok(bytes)) => Some(DaemonTcp::Data(TcpData { + connection_id, + bytes: bytes.to_vec(), + })), + Some(Err(err)) => { + error!("connection id {connection_id:?} read error: {err:?}"); + None + } + None => Some(DaemonTcp::Close(TcpClose { connection_id })), + } + } +} + +pub async fn steal_worker( + rx: Receiver, + tx: Sender, + pid: Option, +) -> Result<()> { + if let Some(pid) = pid { + let namespace = PathBuf::from("/proc") + .join(PathBuf::from(pid.to_string())) + .join(PathBuf::from("ns/net")); + + set_namespace(namespace)?; + } + debug!("preparing steal"); + let listener = TcpListener::bind("0.0.0.0:0").await?; + let listen_port = listener.local_addr()?.port(); + let mut worker = StealWorker::new(tx, listen_port)?; + debug!("finished preparing steal"); + worker.handle_loop(rx, listener).await?; + debug!("steal exiting"); + + Ok(()) +} + +// orig_dst borrowed from linkerd2-proxy +// https://github.com/linkerd/linkerd2-proxy/blob/main/linkerd/proxy/transport/src/orig_dst.rs +// copyright 2018 the linkerd2-proxy authors +mod orig_dst { + use std::{io, net::SocketAddr}; + + use tokio::net::TcpStream; + + #[cfg(target_os = "linux")] + #[allow(unsafe_code)] + pub fn orig_dst_addr(sock: &TcpStream) -> io::Result { + use std::os::unix::io::AsRawFd; + let fd = sock.as_raw_fd(); + unsafe { linux::so_original_dst(fd) } + } + + #[cfg(not(target_os = "linux"))] + pub fn orig_dst_addr(_: &TcpStream) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "SO_ORIGINAL_DST not supported on this operating system", + )) + } + + #[cfg(target_os = "linux")] + #[allow(unsafe_code)] + mod linux { + use std::{ + io, mem, + net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}, + os::unix::io::RawFd, + }; + + use tracing::warn; + + pub unsafe fn so_original_dst(fd: RawFd) -> io::Result { + let mut sockaddr: libc::sockaddr_storage = mem::zeroed(); + let mut socklen: libc::socklen_t = mem::size_of::() as u32; + + let ret = libc::getsockopt( + fd, + libc::SOL_IP, + libc::SO_ORIGINAL_DST, + &mut sockaddr as *mut _ as *mut _, + &mut socklen as *mut _ as *mut _, + ); + if ret != 0 { + let e = io::Error::last_os_error(); + warn!("failed to read SO_ORIGINAL_DST: {:?}", e); + return Err(e); + } + + mk_addr(&sockaddr, socklen) + } + + // Borrowed with love from net2-rs + // https://github.com/rust-lang-nursery/net2-rs/blob/1b4cb4fb05fbad750b271f38221eab583b666e5e/src/socket.rs#L103 + // + // Copyright (c) 2014 The Rust Project Developers + fn mk_addr( + storage: &libc::sockaddr_storage, + len: libc::socklen_t, + ) -> io::Result { + match storage.ss_family as libc::c_int { + libc::AF_INET => { + assert!(len as usize >= mem::size_of::()); + + let sa = { + let sa = storage as *const _ as *const libc::sockaddr_in; + unsafe { *sa } + }; + + let bits = ntoh32(sa.sin_addr.s_addr); + let ip = Ipv4Addr::new( + (bits >> 24) as u8, + (bits >> 16) as u8, + (bits >> 8) as u8, + bits as u8, + ); + let port = sa.sin_port; + Ok(SocketAddr::V4(SocketAddrV4::new(ip, ntoh16(port)))) + } + libc::AF_INET6 => { + assert!(len as usize >= mem::size_of::()); + + let sa = { + let sa = storage as *const _ as *const libc::sockaddr_in6; + unsafe { *sa } + }; + + let arr = sa.sin6_addr.s6_addr; + let ip = Ipv6Addr::new( + (arr[0] as u16) << 8 | (arr[1] as u16), + (arr[2] as u16) << 8 | (arr[3] as u16), + (arr[4] as u16) << 8 | (arr[5] as u16), + (arr[6] as u16) << 8 | (arr[7] as u16), + (arr[8] as u16) << 8 | (arr[9] as u16), + (arr[10] as u16) << 8 | (arr[11] as u16), + (arr[12] as u16) << 8 | (arr[13] as u16), + (arr[14] as u16) << 8 | (arr[15] as u16), + ); + + let port = sa.sin6_port; + let flowinfo = sa.sin6_flowinfo; + let scope_id = sa.sin6_scope_id; + Ok(SocketAddr::V6(SocketAddrV6::new( + ip, + ntoh16(port), + flowinfo, + scope_id, + ))) + } + _ => Err(io::Error::new( + io::ErrorKind::InvalidInput, + "invalid argument", + )), + } + } + + fn ntoh16(i: u16) -> u16 { + ::from_be(i) + } + + fn ntoh32(i: u32) -> u32 { + ::from_be(i) + } + } +} diff --git a/mirrord-agent/src/util.rs b/mirrord-agent/src/util.rs index f30f135c4b8..60ce8bc9bb8 100644 --- a/mirrord-agent/src/util.rs +++ b/mirrord-agent/src/util.rs @@ -138,7 +138,7 @@ where T::Output: Send + 'static, { std::thread::spawn(move || { - let rt = tokio::runtime::Builder::new_current_thread() + let rt = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap(); diff --git a/mirrord-cli/src/config.rs b/mirrord-cli/src/config.rs index 912ee7e0248..fad3b878e54 100644 --- a/mirrord-cli/src/config.rs +++ b/mirrord-cli/src/config.rs @@ -83,6 +83,10 @@ pub(super) struct ExecArgs { #[clap(short, long, value_parser)] pub ephemeral_container: bool, + /// Steal TCP instead of mirroring + #[clap(long, value_parser)] + pub tcp_steal: bool, + /// Enable tcp outgoing feature. #[clap(short = 'o', long, value_parser)] pub enable_tcp_outgoing: bool, diff --git a/mirrord-cli/src/main.rs b/mirrord-cli/src/main.rs index d99cb796b8f..d538aad125e 100644 --- a/mirrord-cli/src/main.rs +++ b/mirrord-cli/src/main.rs @@ -138,6 +138,10 @@ fn exec(args: &ExecArgs) -> Result<()> { std::env::set_var("MIRRORD_EPHEMERAL_CONTAINER", "true"); }; + if args.tcp_steal { + std::env::set_var("MIRRORD_AGENT_TCP_STEAL_TRAFFIC", "true"); + }; + if args.enable_tcp_outgoing { std::env::set_var("MIRRORD_TCP_OUTGOING", true.to_string()); } diff --git a/mirrord-layer/Cargo.lock b/mirrord-layer/Cargo.lock deleted file mode 100644 index 7e7e8c74973..00000000000 --- a/mirrord-layer/Cargo.lock +++ /dev/null @@ -1,2682 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix-codec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "log", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backoff" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" -dependencies = [ - "getrandom", - "instant", - "rand 0.8.5", -] - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bincode" -version = "2.0.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f609ceb2c41b0d0277314a789ef0e7eb14593d5485f7c67320bed3924ebb1b33" -dependencies = [ - "bincode_derive", -] - -[[package]] -name = "bincode_derive" -version = "2.0.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "913287a8f3e00db4c7ae1b87e9b9b8cebd6b89217eaadfc281fa5c897da35dc3" -dependencies = [ - "virtue", -] - -[[package]] -name = "bindgen" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "clap 2.34.0", - "env_logger 0.8.4", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "which", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "capstone" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b5d1f14c3539b6ff22fcb602fea5f1c4416148c8b7965a2e74860aa169b7b5" -dependencies = [ - "capstone-sys", - "libc", -] - -[[package]] -name = "capstone-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df653a22d0ad34b0d91cc92a6289d96e44aac1c9a96250a094c9aeec4a91084f" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cexpr" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "serde", - "winapi", -] - -[[package]] -name = "clang-sys" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap" -version = "3.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c167e37342afc5f33fd87bbc870cedd020d2a6dffa05d45ccd9241fbdd146db" -dependencies = [ - "atty", - "bitflags", - "clap_derive", - "clap_lex", - "indexmap", - "lazy_static", - "strsim 0.10.0", - "termcolor", - "textwrap 0.15.0", -] - -[[package]] -name = "clap_derive" -version = "3.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctor" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "env_logger" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "filetime" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "winapi", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "frida-build" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c4d5d5eedcceaae76eae494338aee0b8fceab952934568287b834d555e01a0a" -dependencies = [ - "reqwest", - "tar", - "xz", -] - -[[package]] -name = "frida-gum" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e2d59d3b7986689332e52cee912200c79ed7db1ab5085b0f109987f3c239e8" -dependencies = [ - "capstone", - "capstone-sys", - "frida-gum-sys", - "num", - "num-derive", - "num-traits", - "paste", - "thiserror", -] - -[[package]] -name = "frida-gum-sys" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1783513909bdc7b7699b8bac67c92c835ab78d3c86fde514f161eb5b88264a66" -dependencies = [ - "bindgen", - "frida-build", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "futures" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-executor" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "h2" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "http" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - -[[package]] -name = "httparse" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-openssl" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ee5d7a8f718585d1c3c61dfde28ef5b0bb14734b4db13f5ada856cdc6c612b" -dependencies = [ - "http", - "hyper", - "linked_hash_set", - "once_cell", - "openssl", - "openssl-sys", - "parking_lot", - "tokio", - "tokio-openssl", - "tower-layer", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-extras" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90f9c8f5bda269ce32e960d433de3fc932ab8f347500e866da45ec70f67e0d2" -dependencies = [ - "io-lifetimes", - "winapi", -] - -[[package]] -name = "io-lifetimes" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9448015e586b611e5d322f6703812bbca2f1e709d5773ecd38ddb4e3bb649504" - -[[package]] -name = "ipnet" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "js-sys" -version = "0.3.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json-patch" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" -dependencies = [ - "serde", - "serde_json", - "treediff", -] - -[[package]] -name = "jsonpath_lib" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaa63191d68230cccb81c5aa23abd53ed64d83337cacbb25a7b8c7979523774f" -dependencies = [ - "log", - "serde", - "serde_json", -] - -[[package]] -name = "k8s-openapi" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0489fc937cc7616a9abfa61bf39c250d7e32e1325ef028c8d9278dd24ea395b3" -dependencies = [ - "base64", - "bytes", - "chrono", - "http", - "percent-encoding", - "serde", - "serde-value", - "serde_json", - "url", -] - -[[package]] -name = "kube" -version = "0.71.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342744dfeb81fe186b84f485b33f12c6a15d3396987d933b06a566a3db52ca38" -dependencies = [ - "k8s-openapi", - "kube-client", - "kube-core", - "kube-derive", - "kube-runtime", -] - -[[package]] -name = "kube-client" -version = "0.71.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f69a504997799340408635d6e351afb8aab2c34ca3165e162f41b3b34a69a79" -dependencies = [ - "base64", - "bytes", - "chrono", - "dirs-next", - "either", - "futures", - "http", - "http-body", - "hyper", - "hyper-openssl", - "hyper-timeout", - "jsonpath_lib", - "k8s-openapi", - "kube-core", - "openssl", - "pem", - "pin-project", - "rand 0.8.5", - "secrecy", - "serde", - "serde_json", - "serde_yaml", - "thiserror", - "tokio", - "tokio-tungstenite", - "tokio-util", - "tower", - "tower-http", - "tracing", -] - -[[package]] -name = "kube-core" -version = "0.71.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a247487699941baaf93438d65b12d4e32450bea849d619d19ed394e8a4a645" -dependencies = [ - "chrono", - "form_urlencoded", - "http", - "json-patch", - "k8s-openapi", - "once_cell", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "kube-derive" -version = "0.71.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203f7c5acf9d0dfb0b08d44ec1d66ace3d1dfe0cdd82e65e274f3f96615d666c" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "serde_json", - "syn", -] - -[[package]] -name = "kube-runtime" -version = "0.71.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02ea50e6ed56578e1d1d02548901b12fe6d3edbf110269a396955e285d487973" -dependencies = [ - "ahash", - "backoff", - "derivative", - "futures", - "json-patch", - "k8s-openapi", - "kube-client", - "parking_lot", - "pin-project", - "serde", - "serde_json", - "smallvec", - "thiserror", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.124" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" - -[[package]] -name = "libloading" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "linked_hash_set" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "linux-raw-sys" -version = "0.0.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5284f00d480e1c39af34e72f8ad60b94f47007e3481cd3b731c1d67190ddc7b7" - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "lzma-sys" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb4b7c3eddad11d3af9e86c487607d2d2442d185d848575365c4856ba96d619" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "mirrord-layer" -version = "0.1.0" -dependencies = [ - "actix-codec", - "bytes", - "clap 3.1.12", - "ctor", - "env_logger 0.9.0", - "frida-gum", - "futures", - "k8s-openapi", - "kube", - "lazy_static", - "libc", - "mirrord-protocol", - "multi-map", - "nanoid", - "nix", - "os_socketaddr", - "queues", - "rand 0.8.5", - "redhook", - "serde_json", - "socketpair", - "tempdir", - "tokio", - "tokio-stream", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "mirrord-protocol" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbfe7bbae9865f066c1816d2389e299be202adc406979b3baba579bf157dc821" -dependencies = [ - "actix-codec", - "bincode", - "bytes", -] - -[[package]] -name = "multi-map" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba551d6d795f74a01767577ea8339560bf0a65354e0417b7e915ed608443d46" - -[[package]] -name = "nanoid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" -dependencies = [ - "rand 0.8.5", -] - -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nix" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" -dependencies = [ - "bitflags", - "cc", - "cfg-if", - "libc", - "memoffset", -] - -[[package]] -name = "nom" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "memchr", - "version_check", -] - -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - -[[package]] -name = "num" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" - -[[package]] -name = "openssl" -version = "0.10.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "ordered-float" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" -dependencies = [ - "num-traits", -] - -[[package]] -name = "os_socketaddr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ff86dee67903f9ffcc3f09712b934761ace77cd34021848a474e7ed7199bd2" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" - -[[package]] -name = "parking_lot" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "paste" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9a3b09a20e374558580a4914d3b7d89bd61b954a5a5e1dcbea98753addb1947" -dependencies = [ - "base64", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pin-project" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "queues" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1475abae4f8ad4998590fe3acfe20104f0a5d48fc420c817cd2c09c3f56151f0" - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redhook" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6e109b8469dbbe6d7cbe18e5ebd65d4a134e2f4b91304ad9213984cad1d70a6" -dependencies = [ - "libc", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.34.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f5d1c6ed6d1c6915aa64749b809fc1bafff49d160f5d927463658093d7d62ab" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "winapi", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "schemars" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "secrecy" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" -dependencies = [ - "serde", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_yaml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" -dependencies = [ - "indexmap", - "ryu", - "serde", - "yaml-rust", -] - -[[package]] -name = "sha-1" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socketpair" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4a66c5734072f44d758e9dbd4f1f0f041687c782535ce7a5428228c752b1a4" -dependencies = [ - "io-extras", - "io-lifetimes", - "rustix", - "uuid", - "winapi", -] - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tar" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "tempdir" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -dependencies = [ - "rand 0.4.6", - "remove_dir_all", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - -[[package]] -name = "thiserror" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-openssl" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08f9ffb7809f1b20c1b398d92acf4cc719874b3b2b2d9ea2f09b4a80350878a" -dependencies = [ - "futures-util", - "openssl", - "openssl-sys", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06cda1232a49558c46f8a504d5b93101d42c0bf7f911f12a105ba48168f821ae" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite", -] - -[[package]] -name = "tokio-util" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "slab", - "tokio", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8" -dependencies = [ - "base64", - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" - -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - -[[package]] -name = "tracing" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" -dependencies = [ - "lazy_static", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" -dependencies = [ - "ansi_term", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "treediff" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" -dependencies = [ - "serde_json", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "tungstenite" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5" -dependencies = [ - "base64", - "byteorder", - "bytes", - "http", - "httparse", - "log", - "rand 0.8.5", - "sha-1", - "thiserror", - "url", - "utf-8", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "unicode-bidi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "virtue" -version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757cfbfe0d17ee6f22fe97e536d463047d451b47cf9d11e2b7d1398b0ef274dd" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" - -[[package]] -name = "web-sys" -version = "0.3.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "which" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" -dependencies = [ - "libc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" - -[[package]] -name = "windows_i686_gnu" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" - -[[package]] -name = "windows_i686_msvc" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "xattr" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" -dependencies = [ - "libc", -] - -[[package]] -name = "xz" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34" -dependencies = [ - "xz2", -] - -[[package]] -name = "xz2" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" -dependencies = [ - "lzma-sys", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "zeroize" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb5728b8afd3f280a869ce1d4c554ffaed35f45c231fc41bfbd0381bef50317" diff --git a/mirrord-layer/Cargo.toml b/mirrord-layer/Cargo.toml index a6a84b10aa0..e65a0dc778c 100644 --- a/mirrord-layer/Cargo.toml +++ b/mirrord-layer/Cargo.toml @@ -34,6 +34,7 @@ serde_json.workspace = true actix-codec.workspace = true bytes.workspace = true tokio-stream.workspace = true +tokio-util.workspace = true thiserror.workspace = true dns-lookup.workspace = true rand = "0.8" @@ -42,6 +43,8 @@ regex = "1" errno = "0.2" async-trait = "0.1" socket2 = "0.4" +anyhow.workspace = true +streammap-ext.workspace = true stacker = "0.1" [lib] diff --git a/mirrord-layer/src/config.rs b/mirrord-layer/src/config.rs index a69863297c4..fd16a360a31 100644 --- a/mirrord-layer/src/config.rs +++ b/mirrord-layer/src/config.rs @@ -29,6 +29,9 @@ pub struct LayerConfig { #[envconfig(from = "MIRRORD_AGENT_TTL", default = "0")] pub agent_ttl: u16, + #[envconfig(from = "MIRRORD_AGENT_TCP_STEAL_TRAFFIC", default = "false")] + pub agent_tcp_steal_traffic: bool, + #[envconfig(from = "MIRRORD_AGENT_COMMUNICATION_TIMEOUT")] pub agent_communication_timeout: Option, diff --git a/mirrord-layer/src/error.rs b/mirrord-layer/src/error.rs index 0d291993b6e..6e8f79adcb0 100644 --- a/mirrord-layer/src/error.rs +++ b/mirrord-layer/src/error.rs @@ -102,14 +102,17 @@ pub(crate) enum LayerError { #[error("mirrord-layer: Failed to get `Sender` for sending getaddrinfo response!")] SendErrorGetAddrInfoResponse, + #[error("mirrord-layer: IO failed with `{0}`!")] + IO(#[from] std::io::Error), + #[error("mirrord-layer: No connection found for id `{0}`!")] NoConnectionId(ConnectionId), #[error("mirrord-layer: Failed to find port `{0}`!")] PortNotFound(u16), - #[error("mirrord-layer: Failed to find connection_id `{0}`!")] - ConnectionIdNotFound(ConnectionId), + #[error("mirrord-layer: Failed inserting listen, already exists!")] + ListenAlreadyExists, #[error("mirrord-layer: Unmatched pong!")] UnmatchedPong, @@ -131,12 +134,6 @@ pub(crate) enum LayerError { #[error("mirrord-layer: Container `{0}` not found in namespace `{1}` pod `{2}`")] ContainerNotFound(String, String, String), - - #[error("mirrord-layer: IO failed with `{0}`!")] - IO(#[from] std::io::Error), - - #[error("mirrord-layer: Failed inserting listen, already exists!")] - ListenAlreadyExists, } // Cannot have a generic From implementation for this error, so explicitly implemented here. diff --git a/mirrord-layer/src/lib.rs b/mirrord-layer/src/lib.rs index 54be687080e..69a17278f67 100644 --- a/mirrord-layer/src/lib.rs +++ b/mirrord-layer/src/lib.rs @@ -30,6 +30,7 @@ use rand::Rng; use socket::SOCKETS; use tcp::{outgoing::TcpOutgoingHandler, TcpHandler}; use tcp_mirror::TcpMirrorHandler; +use tcp_steal::TcpStealHandler; use tokio::{ runtime::Runtime, select, @@ -53,6 +54,7 @@ mod pod_api; mod socket; mod tcp; mod tcp_mirror; +mod tcp_steal; static RUNTIME: LazyLock = LazyLock::new(|| { tokio::runtime::Builder::new_multi_thread() @@ -126,13 +128,17 @@ where // Stores a list of `oneshot`s that communicates with the hook side (send a message from -layer // to -agent, and when we receive a message from -agent to -layer). getaddrinfo_handler_queue: VecDeque>>, + + pub tcp_steal_handler: TcpStealHandler, + + steal: bool, } impl Layer where T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, { - fn new(codec: actix_codec::Framed) -> Layer { + fn new(codec: actix_codec::Framed, steal: bool) -> Layer { Self { codec, ping: false, @@ -140,6 +146,8 @@ where tcp_outgoing_handler: TcpOutgoingHandler::default(), file_handler: FileHandler::default(), getaddrinfo_handler_queue: VecDeque::new(), + tcp_steal_handler: TcpStealHandler::default(), + steal, } } @@ -151,10 +159,17 @@ where match hook_message { HookMessage::Tcp(message) => { - self.tcp_mirror_handler - .handle_hook_message(message, &mut self.codec) - .await - .unwrap(); + if self.steal { + self.tcp_steal_handler + .handle_hook_message(message, &mut self.codec) + .await + .unwrap(); + } else { + self.tcp_mirror_handler + .handle_hook_message(message, &mut self.codec) + .await + .unwrap(); + } } HookMessage::File(message) => { self.file_handler @@ -193,6 +208,9 @@ where DaemonMessage::Tcp(message) => { self.tcp_mirror_handler.handle_daemon_message(message).await } + DaemonMessage::TcpSteal(message) => { + self.tcp_steal_handler.handle_daemon_message(message).await + } DaemonMessage::File(message) => self.file_handler.handle_daemon_message(message).await, DaemonMessage::TcpOutgoing(message) => { self.tcp_outgoing_handler @@ -233,8 +251,9 @@ async fn thread_loop( impl tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, ClientCodec, >, + steal: bool, ) { - let mut layer = Layer::new(codec); + let mut layer = Layer::new(codec, steal); loop { select! { hook_message = receiver.recv() => { @@ -267,6 +286,9 @@ async fn thread_loop( } } }, + Some(message) = layer.tcp_steal_handler.next() => { + layer.codec.send(message).await.unwrap(); + }, _ = sleep(Duration::from_secs(60)) => { if !layer.ping { layer.codec.send(ClientMessage::Ping).await.unwrap(); @@ -332,10 +354,10 @@ async fn start_layer_thread( } else { panic!("unexpected response - expected env vars response {msg:?}"); } - } + }; } - let _ = tokio::spawn(thread_loop(receiver, codec)); + let _ = tokio::spawn(thread_loop(receiver, codec, config.agent_tcp_steal_traffic)); } /// Enables file (behind `MIRRORD_FILE_OPS` option) and socket hooks. diff --git a/mirrord-layer/src/pod_api.rs b/mirrord-layer/src/pod_api.rs index 39a96a814a4..0dadd0e8071 100644 --- a/mirrord-layer/src/pod_api.rs +++ b/mirrord-layer/src/pod_api.rs @@ -212,6 +212,12 @@ async fn create_ephemeral_container_agent( let ephemeral_container: EphemeralContainer = serde_json::from_value(json!({ "name": mirrord_agent_name, "image": agent_image, + "securityContext": { + "capabilities": { + "add": ["NET_RAW", "NET_ADMIN"], + }, + "privileged": true, + }, "imagePullPolicy": config.image_pull_policy, "targetContainerName": config.impersonated_container_name, "env": [{"name": "RUST_LOG", "value": config.agent_rust_log}], diff --git a/mirrord-layer/src/tcp.rs b/mirrord-layer/src/tcp.rs index ed8ec635479..b8934d3a14c 100644 --- a/mirrord-layer/src/tcp.rs +++ b/mirrord-layer/src/tcp.rs @@ -9,10 +9,9 @@ use std::{ }; use async_trait::async_trait; -use futures::SinkExt; use mirrord_protocol::{ - tcp::{DaemonTcp, LayerTcp, NewTcpConnection, TcpClose, TcpData}, - ClientCodec, ClientMessage, Port, + tcp::{DaemonTcp, NewTcpConnection, TcpClose, TcpData}, + ClientCodec, Port, }; use tokio::net::TcpStream; use tracing::{debug, trace}; @@ -164,19 +163,5 @@ pub(crate) trait TcpHandler { impl tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, ClientCodec, >, - ) -> Result<(), LayerError> { - debug!("handle_listen -> listen {:#?}", listen); - - let port = listen.requested_port; - - self.ports_mut() - .insert(listen) - .then_some(()) - .ok_or(LayerError::ListenAlreadyExists)?; - - codec - .send(ClientMessage::Tcp(LayerTcp::PortSubscribe(port))) - .await - .map_err(From::from) - } + ) -> Result<(), LayerError>; } diff --git a/mirrord-layer/src/tcp_mirror.rs b/mirrord-layer/src/tcp_mirror.rs index 8c084be93c7..48f6e040229 100644 --- a/mirrord-layer/src/tcp_mirror.rs +++ b/mirrord-layer/src/tcp_mirror.rs @@ -6,9 +6,10 @@ use std::{ }; use async_trait::async_trait; +use futures::SinkExt; use mirrord_protocol::{ - tcp::{NewTcpConnection, TcpClose, TcpData}, - ConnectionId, + tcp::{LayerTcp, NewTcpConnection, TcpClose, TcpData}, + ClientCodec, ClientMessage, ConnectionId, }; use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, @@ -122,7 +123,7 @@ pub struct TcpMirrorHandler { impl TcpHandler for TcpMirrorHandler { /// Handle NewConnection messages async fn handle_new_connection(&mut self, tcp_connection: NewTcpConnection) -> Result<()> { - trace!("handle_new_connection -> {:#?}", tcp_connection); + debug!("handle_new_connection -> {:#?}", tcp_connection); let stream = self.create_local_stream(&tcp_connection).await?; @@ -172,7 +173,7 @@ impl TcpHandler for TcpMirrorHandler { self.connections .remove(&connection_id) .then_some(()) - .ok_or(LayerError::ConnectionIdNotFound(connection_id)) + .ok_or(LayerError::NoConnectionId(connection_id)) } fn ports(&self) -> &HashSet { @@ -182,4 +183,27 @@ impl TcpHandler for TcpMirrorHandler { fn ports_mut(&mut self) -> &mut HashSet { &mut self.ports } + + async fn handle_listen( + &mut self, + listen: Listen, + codec: &mut actix_codec::Framed< + impl tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, + ClientCodec, + >, + ) -> Result<()> { + debug!("handle_listen -> listen {:#?}", listen); + + let port = listen.requested_port; + + self.ports_mut() + .insert(listen) + .then_some(()) + .ok_or(LayerError::ListenAlreadyExists)?; + + codec + .send(ClientMessage::Tcp(LayerTcp::PortSubscribe(port))) + .await + .map_err(From::from) + } } diff --git a/mirrord-layer/src/tcp_steal.rs b/mirrord-layer/src/tcp_steal.rs new file mode 100644 index 00000000000..a2d97937e01 --- /dev/null +++ b/mirrord-layer/src/tcp_steal.rs @@ -0,0 +1,137 @@ +use std::collections::{HashMap, HashSet}; + +use anyhow::Result; +use async_trait::async_trait; +use futures::SinkExt; +use mirrord_protocol::{ + tcp::{LayerTcpSteal, NewTcpConnection, TcpClose, TcpData}, + ClientCodec, ClientMessage, ConnectionId, +}; +use streammap_ext::StreamMap; +use tokio::{ + io::{AsyncWriteExt, ReadHalf, WriteHalf}, + net::TcpStream, +}; +use tokio_stream::StreamExt; +use tokio_util::io::ReaderStream; +use tracing::{debug, error}; + +use crate::{ + error::LayerError, + tcp::{Listen, TcpHandler}, +}; + +#[derive(Default)] +pub struct TcpStealHandler { + ports: HashSet, + write_streams: HashMap>, + read_streams: StreamMap>>, +} + +#[async_trait] +impl TcpHandler for TcpStealHandler { + async fn handle_new_connection( + &mut self, + tcp_connection: NewTcpConnection, + ) -> Result<(), LayerError> { + debug!("handle_new_connection -> {:#?}", tcp_connection); + + let stream = self.create_local_stream(&tcp_connection).await?; + + let (read_half, write_half) = tokio::io::split(stream); + self.write_streams + .insert(tcp_connection.connection_id, write_half); + self.read_streams + .insert(tcp_connection.connection_id, ReaderStream::new(read_half)); + + Ok(()) + } + + async fn handle_new_data(&mut self, data: TcpData) -> Result<(), LayerError> { + debug!("handle_new_data -> id {:#?}", data.connection_id); + + // TODO: "remove -> op -> insert" pattern here, maybe we could improve the overlying + // abstraction to use something that has mutable access. + let mut connection = self + .write_streams + .remove(&data.connection_id) + .ok_or(LayerError::NoConnectionId(data.connection_id))?; + + debug!( + "handle_new_data -> writing {:#?} bytes to id {:#?}", + data.bytes.len(), + data.connection_id + ); + // TODO: Due to the above, if we fail here this connection is leaked (-agent won't be told + // that we just removed it). + connection.write_all(&data.bytes[..]).await?; + + self.write_streams.insert(data.connection_id, connection); + debug!("handle_new_data -> success"); + + Ok(()) + } + + fn handle_close(&mut self, close: TcpClose) -> Result<(), LayerError> { + debug!("handle_close -> close {:#?}", close); + + let TcpClose { connection_id } = close; + + // Dropping the connection -> Sender drops -> Receiver disconnects -> tcp_tunnel ends + let _ = self.read_streams.remove(&connection_id); + + let _ = self.write_streams.remove(&connection_id); + + Ok(()) + } + + fn ports(&self) -> &HashSet { + &self.ports + } + + fn ports_mut(&mut self) -> &mut HashSet { + &mut self.ports + } + + async fn handle_listen( + &mut self, + listen: Listen, + codec: &mut actix_codec::Framed< + impl tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, + ClientCodec, + >, + ) -> Result<(), LayerError> { + debug!("handle_listen -> listen {:#?}", listen); + + let port = listen.requested_port; + + self.ports_mut() + .insert(listen) + .then_some(()) + .ok_or(LayerError::ListenAlreadyExists)?; + + codec + .send(ClientMessage::TcpSteal(LayerTcpSteal::PortSubscribe(port))) + .await + .map_err(From::from) + } +} + +impl TcpStealHandler { + pub async fn next(&mut self) -> Option { + let (connection_id, value) = self.read_streams.next().await?; + match value { + Some(Ok(bytes)) => Some(ClientMessage::TcpSteal(LayerTcpSteal::Data(TcpData { + connection_id, + bytes: bytes.to_vec(), + }))), + Some(Err(err)) => { + error!("connection id {connection_id:?} read error: {err:?}"); + None + } + None => Some(ClientMessage::TcpSteal( + LayerTcpSteal::ConnectionUnsubscribe(connection_id), + )), + } + } +} diff --git a/mirrord-protocol/src/codec.rs b/mirrord-protocol/src/codec.rs index b264ddef08a..f182b032eec 100644 --- a/mirrord-protocol/src/codec.rs +++ b/mirrord-protocol/src/codec.rs @@ -12,7 +12,7 @@ use bytes::{Buf, BufMut, BytesMut}; use crate::{ tcp::{ outgoing::{DaemonTcpOutgoing, LayerTcpOutgoing}, - DaemonTcp, LayerTcp, + DaemonTcp, LayerTcp, LayerTcpSteal, }, ResponseError, }; @@ -169,6 +169,7 @@ pub struct GetAddrInfoRequest { pub enum ClientMessage { Close, Tcp(LayerTcp), + TcpSteal(LayerTcpSteal), TcpOutgoing(LayerTcpOutgoing), FileRequest(FileRequest), GetEnvVarsRequest(GetEnvVarsRequest), @@ -275,6 +276,7 @@ impl From for AddrInfoInternal { pub enum DaemonMessage { Close, Tcp(DaemonTcp), + TcpSteal(DaemonTcp), TcpOutgoing(DaemonTcpOutgoing), LogMessage(LogMessage), File(FileResponse), diff --git a/mirrord-protocol/src/steal.rs b/mirrord-protocol/src/steal.rs new file mode 100644 index 00000000000..5be3b8b7907 --- /dev/null +++ b/mirrord-protocol/src/steal.rs @@ -0,0 +1,16 @@ +use crate::types::*; + + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)] +pub enum StealClientMessage { + PortSteal(Port), + TCPData(TCPData), + CloseConnection(TCPClose), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)] +pub enum StealDaemonMessage { + NewConnection(NewTcpConnection), + TCPData(TCPData), + TCPClose(TCPClose), +} \ No newline at end of file diff --git a/mirrord-protocol/src/tcp.rs b/mirrord-protocol/src/tcp.rs index bbcfb3a71de..625f0cd105b 100644 --- a/mirrord-protocol/src/tcp.rs +++ b/mirrord-protocol/src/tcp.rs @@ -52,3 +52,12 @@ pub enum DaemonTcp { /// flakiness. Subscribed, } + +/// Messages related to Steal Tcp handler from client. +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)] +pub enum LayerTcpSteal { + PortSubscribe(Port), + ConnectionUnsubscribe(ConnectionId), + PortUnsubscribe(Port), + Data(TcpData), +} diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 58064873c10..043da8a648e 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -23,4 +23,5 @@ rand = "*" futures-util = "*" tempdir = "*" wsl = "0.1" -chrono = "0.4" \ No newline at end of file +chrono = "0.4" +bytes = "1" \ No newline at end of file diff --git a/tests/go-e2e/main.go b/tests/go-e2e/main.go index a8906ea74ae..3238ed47e2f 100644 --- a/tests/go-e2e/main.go +++ b/tests/go-e2e/main.go @@ -28,7 +28,7 @@ func main() { r := gin.Default() r.GET("/", func(c *gin.Context) { fmt.Println("GET: Request completed") - c.String(http.StatusOK, "OK") + c.String(http.StatusOK, "GET") }) r.POST("/", func(c *gin.Context) { @@ -37,18 +37,20 @@ func main() { fmt.Printf("POST: Error getting raw data: %v\n", err) } fmt.Println("POST: Request completed") - c.String(http.StatusOK, "OK") + c.String(http.StatusOK, "POST") }) r.PUT("/", func(c *gin.Context) { fmt.Println("PUT: Request completed") - c.String(http.StatusOK, "OK") + c.String(http.StatusOK, "PUT") }) r.DELETE("/", func(c *gin.Context) { fmt.Println("DELETE: Request completed") - syscall.Kill(syscall.Getpid(), syscall.SIGINT) - c.String(http.StatusOK, "OK") + defer func() { + syscall.Kill(syscall.Getpid(), syscall.SIGINT) + }() + c.String(http.StatusOK, "DELETE") }) fmt.Println("Server listening on port 80") diff --git a/tests/node-e2e/app.js b/tests/node-e2e/app.js index eb8a6fae39e..9609a3f3258 100644 --- a/tests/node-e2e/app.js +++ b/tests/node-e2e/app.js @@ -5,19 +5,22 @@ const PORT = 80; app.get("/", (req, res) => { console.log("GET: Request completed"); - res.send("Request received"); // Todo: validate responses + res.send("GET"); }); app.post("/", (req, res) => { console.log("POST: Request completed"); + res.send("POST"); }); app.put("/", (req, res) => { console.log("PUT: Request completed"); + res.send("PUT"); }); app.delete("/", (req, res) => { console.log("DELETE: Request completed"); + res.send("DELETE"); server.close(); process.kill(process.pid) }); diff --git a/tests/python-e2e/app.py b/tests/python-e2e/app.py index 0622efaa5d1..094a7520c1d 100644 --- a/tests/python-e2e/app.py +++ b/tests/python-e2e/app.py @@ -1,9 +1,10 @@ from os import getpid, kill from signal import SIGTERM +import time from flask import Flask import logging import sys -import uuid +import threading log = logging.getLogger("werkzeug") log.disabled = True @@ -16,31 +17,36 @@ TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +def kill_later(): + def kill_thread(): + time.sleep(1) + kill(getpid(), SIGTERM) + threading.Thread(target=kill_thread).start() + @app.route("/", methods=["GET"]) def get(): print("GET: Request completed") - return "OK" + return "GET" @app.route("/", methods=["POST"]) def post(): print("POST: Request completed") - return "OK" + return "POST" @app.route("/", methods=["PUT"]) def put(): print("PUT: Request completed") - return "OK" + return "PUT" @app.route("/", methods=["DELETE"]) def delete(): print("DELETE: Request completed") - # killing Flask is the hardest thing I've done in my life - A.H - kill(getpid(), SIGTERM) - return "OK" + kill_later() + return "DELETE" if __name__ == "__main__": diff --git a/tests/src/sanity.rs b/tests/src/sanity.rs index bc5648cf41d..869f56ab39a 100644 --- a/tests/src/sanity.rs +++ b/tests/src/sanity.rs @@ -11,6 +11,7 @@ mod tests { time::Duration, }; + use bytes::Bytes; use chrono::Utc; use futures_util::stream::{StreamExt, TryStreamExt}; use k8s_openapi::api::{ @@ -501,7 +502,7 @@ mod tests { pod } - pub async fn send_requests(url: &str) { + pub async fn send_requests(url: &str, expect_response: bool) { // Create client for each request until we have a match between local app and remote app // as connection state is flaky println!("{url}"); @@ -509,31 +510,45 @@ mod tests { let res = client.get(url).send().await.unwrap(); assert_eq!(res.status(), StatusCode::OK); // read all data sent back - res.bytes().await.unwrap(); + + let resp = res.bytes().await.unwrap(); + if expect_response { + assert_eq!(resp, Bytes::from("GET")); + } let client = reqwest::Client::new(); let res = client.post(url).body(TEXT).send().await.unwrap(); assert_eq!(res.status(), StatusCode::OK); // read all data sent back - res.bytes().await.unwrap(); + let resp = res.bytes().await.unwrap(); + if expect_response { + assert_eq!(resp, "POST".as_bytes()); + } let client = reqwest::Client::new(); let res = client.put(url).send().await.unwrap(); assert_eq!(res.status(), StatusCode::OK); // read all data sent back - res.bytes().await.unwrap(); + let resp = res.bytes().await.unwrap(); + if expect_response { + assert_eq!(resp, "PUT".as_bytes()); + } let client = reqwest::Client::new(); let res = client.delete(url).send().await.unwrap(); assert_eq!(res.status(), StatusCode::OK); // read all data sent back - res.bytes().await.unwrap(); + let resp = res.bytes().await.unwrap(); + if expect_response { + assert_eq!(resp, "DELETE".as_bytes()); + } } #[cfg(target_os = "linux")] #[rstest] #[trace] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] async fn test_mirror_http_traffic( #[future] #[notrace] @@ -551,7 +566,7 @@ mod tests { .run(&service.pod_name, Some(&service.namespace), agent.flag()) .await; process.wait_for_line(Duration::from_secs(120), "daemon subscribed"); - send_requests(&url).await; + send_requests(&url, false).await; process.wait_for_line(Duration::from_secs(10), "GET"); process.wait_for_line(Duration::from_secs(10), "POST"); process.wait_for_line(Duration::from_secs(10), "PUT"); @@ -567,6 +582,7 @@ mod tests { #[rstest] #[trace] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] async fn test_mirror_http_traffic( #[future] #[notrace] @@ -584,7 +600,7 @@ mod tests { .run(&service.pod_name, Some(&service.namespace), agent.flag()) .await; process.wait_for_line(Duration::from_secs(300), "daemon subscribed"); - send_requests(&url).await; + send_requests(&url, false).await; process.wait_for_line(Duration::from_secs(10), "GET"); process.wait_for_line(Duration::from_secs(10), "POST"); process.wait_for_line(Duration::from_secs(10), "PUT"); @@ -600,6 +616,7 @@ mod tests { #[rstest] #[trace] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_file_ops( #[future] #[notrace] @@ -633,6 +650,7 @@ mod tests { #[rstest] #[trace] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_file_ops( #[future] #[notrace] @@ -663,6 +681,7 @@ mod tests { #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_remote_env_vars_exclude_works(#[future] service: EchoService) { let service = service.await; let node_command = vec![ @@ -679,6 +698,7 @@ mod tests { #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_remote_env_vars_include_works(#[future] service: EchoService) { let service = service.await; let node_command = vec![ @@ -695,6 +715,7 @@ mod tests { #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_remote_dns_enabled_works(#[future] service: EchoService) { let service = service.await; let node_command = vec![ @@ -711,6 +732,7 @@ mod tests { #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_remote_dns_lookup_google(#[future] service: EchoService) { let service = service.await; let node_command = vec![ @@ -727,6 +749,7 @@ mod tests { #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_remote_dns_lookup_pod_service(#[future] service: EchoService) { let service = service.await; let node_command = vec![ @@ -741,9 +764,38 @@ mod tests { process.assert_stderr(); } + #[cfg(target_os = "linux")] + #[rstest] + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] + async fn test_steal_http_traffic( + #[future] service: EchoService, + #[future] kube_client: Client, + #[values(Application::PythonHTTP, Application::NodeHTTP)] application: Application, + #[values(Agent::Ephemeral, Agent::Job)] agent: Agent, + ) { + let service = service.await; + let kube_client = kube_client.await; + let url = get_service_url(kube_client.clone(), &service).await; + let mut flags = vec!["--tcp-steal"]; + agent.flag().map(|flag| flags.extend(flag)); + let mut process = application + .run(&service.pod_name, Some(&service.namespace), Some(flags)) + .await; + + process.wait_for_line(Duration::from_secs(30), "daemon subscribed"); + send_requests(&url, true).await; + timeout(Duration::from_secs(40), process.child.wait()) + .await + .unwrap() + .unwrap(); + process.assert_stderr(); + } + #[rstest] #[cfg(target_os = "linux")] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_bash_remote_env_vars_works(#[future] service: EchoService) { let service = service.await; let bash_command = vec!["bash", "bash-e2e/env.sh"]; @@ -758,6 +810,7 @@ mod tests { #[rstest] #[cfg(target_os = "linux")] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_bash_remote_env_vars_exclude_works(#[future] service: EchoService) { let service = service.await; let bash_command = vec!["bash", "bash-e2e/env.sh", "exclude"]; @@ -772,6 +825,7 @@ mod tests { #[rstest] #[cfg(target_os = "linux")] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_bash_remote_env_vars_include_works(#[future] service: EchoService) { let service = service.await; let bash_command = vec!["bash", "bash-e2e/env.sh", "include"]; @@ -789,6 +843,7 @@ mod tests { #[cfg(target_os = "linux")] #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_bash_file_exists(#[future] service: EchoService) { let service = service.await; let bash_command = vec!["bash", "bash-e2e/file.sh", "exists"]; @@ -807,6 +862,7 @@ mod tests { #[cfg(target_os = "linux")] #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_bash_file_read(#[future] service: EchoService) { let service = service.await; let bash_command = vec!["bash", "bash-e2e/file.sh", "read"]; @@ -822,6 +878,7 @@ mod tests { #[cfg(target_os = "linux")] #[rstest] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + #[timeout(Duration::from_secs(240))] pub async fn test_bash_file_write(#[future] service: EchoService) { let service = service.await; let bash_command = vec!["bash", "bash-e2e/file.sh", "write"];