use crate::{ client::{AppHandle, ClientEvent}, net::{SERVER_NAME, no_cert::SkipServerVerification}, }; use quinn::{ClientConfig, Connection, Endpoint, crypto::rustls::QuicClientConfig}; use std::{ net::{Ipv6Addr, SocketAddr, SocketAddrV6, ToSocketAddrs}, str::FromStr, sync::Arc, }; use tokio::sync::mpsc::UnboundedSender; pub const CLIENT_SOCKET: SocketAddr = SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0)); pub fn connect(handle: AppHandle, ip: String) { std::thread::spawn(|| { connect_the(handle, ip).unwrap(); }); } pub enum NetCmd { SendMsg(String), } pub type NetSender = UnboundedSender; // async fn connection_cert(addr: SocketAddr) -> anyhow::Result { // let dirs = directories_next::ProjectDirs::from("", "", "openworm").unwrap(); // let mut roots = quinn::rustls::RootCertStore::empty(); // match fs::read(dirs.data_local_dir().join("cert.der")) { // Ok(cert) => { // roots.add(CertificateDer::from(cert))?; // } // Err(ref e) if e.kind() == ErrorKind::NotFound => { // eprintln!("local server certificate not found"); // } // Err(e) => { // eprintln!("failed to open local server certificate: {}", e); // } // } // let client_crypto = quinn::rustls::ClientConfig::builder() // .with_root_certificates(roots) // .with_no_client_auth(); // let client_config = ClientConfig::new(Arc::new(QuicClientConfig::try_from(client_crypto)?)); // let mut endpoint = quinn::Endpoint::client(SocketAddr::from_str("[::]:0").unwrap())?; // endpoint.set_default_client_config(client_config); // endpoint // .connect(addr, SERVER_NAME)? // .await // .map_err(|e| anyhow::anyhow!("failed to connect: {}", e)) // } async fn connection_no_cert(addr: SocketAddr) -> anyhow::Result { let mut endpoint = Endpoint::client(CLIENT_SOCKET)?; endpoint.set_default_client_config(ClientConfig::new(Arc::new(QuicClientConfig::try_from( quinn::rustls::ClientConfig::builder() .dangerous() .with_custom_certificate_verifier(SkipServerVerification::new()) .with_no_client_auth(), )?))); // connect to server endpoint .connect(addr, SERVER_NAME) .unwrap() .await .map_err(|e| anyhow::anyhow!("failed to connect: {e}")) } #[tokio::main] async fn connect_the(handle: AppHandle, ip: String) -> anyhow::Result<()> { let (client_send, mut client_recv) = tokio::sync::mpsc::unbounded_channel::(); handle.send(ClientEvent::Connect(client_send)); let addr = ip.to_socket_addrs().unwrap().next().unwrap(); // let addr = SocketAddr::from_str(&ip).unwrap(); let conn = connection_no_cert(addr).await?; while let Some(msg) = client_recv.recv().await { match msg { NetCmd::SendMsg(content) => { let (mut send, recv) = conn .open_bi() .await .map_err(|e| anyhow::anyhow!("failed to open stream: {e}"))?; drop(recv); send.write_all(content.as_bytes()) .await .expect("failed to send"); send.finish().unwrap(); send.stopped().await.unwrap(); } } } Ok(()) }