2025-08-30 10:30:25 +09:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
2025-08-24 12:26:44 +09:00
|
|
|
use caretta_sync::{
|
2025-08-23 08:55:25 +09:00
|
|
|
config::P2pConfig,
|
|
|
|
|
proto::cached_peer_service_server::CachedPeerServiceServer,
|
|
|
|
|
server::ServerTrait,
|
2025-09-23 22:20:18 +09:00
|
|
|
rpc::service::iroh::CachedPeerService
|
2025-08-23 08:55:25 +09:00
|
|
|
};
|
2025-08-21 07:40:33 +09:00
|
|
|
use libp2p::{futures::StreamExt, noise, swarm::SwarmEvent, tcp, yamux};
|
2025-08-23 08:55:25 +09:00
|
|
|
use tokio::net::UnixListener;
|
|
|
|
|
use tokio_stream::wrappers::UnixListenerStream;
|
2025-08-24 10:19:06 +09:00
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2025-08-21 07:40:33 +09:00
|
|
|
pub struct Server{}
|
2025-08-20 06:50:35 +09:00
|
|
|
|
|
|
|
|
impl ServerTrait for Server {
|
2025-08-24 12:26:44 +09:00
|
|
|
async fn serve_p2p<T>(config: &T) -> Result<(), caretta_sync::error::Error>
|
2025-08-21 07:40:33 +09:00
|
|
|
where
|
|
|
|
|
T: AsRef<P2pConfig>
|
|
|
|
|
{
|
2025-08-22 07:56:26 +09:00
|
|
|
let mut swarm = libp2p::SwarmBuilder::with_existing_identity(config.as_ref().private_key.clone())
|
2025-08-20 06:50:35 +09:00
|
|
|
.with_tokio()
|
|
|
|
|
.with_tcp(
|
|
|
|
|
tcp::Config::default(),
|
|
|
|
|
noise::Config::new,
|
|
|
|
|
yamux::Config::default,
|
|
|
|
|
)?
|
2025-08-24 12:26:44 +09:00
|
|
|
.with_behaviour(|keypair| caretta_sync::p2p::Behaviour::try_from(keypair).unwrap())?
|
2025-08-20 06:50:35 +09:00
|
|
|
.build();
|
|
|
|
|
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
|
|
|
|
loop{
|
|
|
|
|
let swarm_event = swarm.select_next_some().await;
|
|
|
|
|
tokio::spawn(async move{
|
|
|
|
|
match swarm_event {
|
|
|
|
|
SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"),
|
|
|
|
|
SwarmEvent::Behaviour(event) => {
|
|
|
|
|
println!("{event:?}");
|
|
|
|
|
event.run().await;
|
|
|
|
|
},
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-21 07:40:33 +09:00
|
|
|
|
2025-08-24 12:26:44 +09:00
|
|
|
async fn serve_rpc<T>(config: &T) -> Result<(), caretta_sync::error::Error>
|
|
|
|
|
where T: AsRef<caretta_sync::config::RpcConfig> {
|
2025-08-30 10:30:25 +09:00
|
|
|
let url = config.as_ref().endpoint_url.clone();
|
|
|
|
|
let router = tonic::transport::Server::builder()
|
|
|
|
|
.add_service(CachedPeerServiceServer::new(CachedPeerService::default()));
|
|
|
|
|
match url.scheme() {
|
|
|
|
|
"unix" => {
|
|
|
|
|
let path = PathBuf::from(url.path());
|
|
|
|
|
if let Some(x) = path.parent() {
|
|
|
|
|
if !x.exists() {
|
|
|
|
|
std::fs::create_dir_all(x).expect("Failed to create directory for socket file!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if path.exists() {
|
|
|
|
|
std::fs::remove_file(&path).expect("Failed to remove existing socket file!")
|
|
|
|
|
}
|
|
|
|
|
let uds = UnixListener::bind(path).unwrap();
|
|
|
|
|
let uds_stream = UnixListenerStream::new(uds);
|
|
|
|
|
|
|
|
|
|
router.serve_with_incoming(uds_stream)
|
|
|
|
|
.await.unwrap();
|
|
|
|
|
},
|
|
|
|
|
"http" => {
|
|
|
|
|
let host = url.socket_addrs(|| None).expect("http endpoint should have host address and port").pop().unwrap();
|
|
|
|
|
|
|
|
|
|
router.serve(host).await.unwrap();
|
|
|
|
|
},
|
|
|
|
|
_ => {
|
|
|
|
|
Err(caretta_sync::error::Error::Config(caretta_sync::config::ConfigError::InvalidUrl(url)))?;
|
2025-08-23 08:55:25 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
2025-08-21 07:40:33 +09:00
|
|
|
}
|
2025-08-20 06:50:35 +09:00
|
|
|
}
|