use crate::{ client::{AppHandle, ClientEvent}, net::{BINCODE_CONFIG, ClientMsg, SERVER_NAME, no_cert::SkipServerVerification}, }; use quinn::{ClientConfig, Connection, Endpoint, crypto::rustls::QuicClientConfig}; use std::{ net::{Ipv6Addr, SocketAddr, SocketAddrV6, ToSocketAddrs}, sync::Arc, }; use tokio::{io::AsyncWriteExt, 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 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 conn = connection_no_cert(addr).await?; while let Some(msg) = client_recv.recv().await { let bytes = bincode::encode_to_vec(msg, BINCODE_CONFIG).unwrap(); let (mut send, recv) = conn .open_bi() .await .map_err(|e| anyhow::anyhow!("failed to open stream: {e}"))?; drop(recv); send.write_u64(bytes.len() as u64) .await .expect("failed to send"); send.write_all(&bytes).await.expect("failed to send"); send.finish().unwrap(); send.stopped().await.unwrap(); } Ok(()) }