use std::io::Write; use std::net::SocketAddr; use log::info; use structopt::StructOpt; use sodiumoxide::crypto::auth; use sodiumoxide::crypto::sign::ed25519; use netapp::peering::fullmesh::*; use netapp::NetApp; use netapp::NodeID; #[derive(StructOpt, Debug)] #[structopt(name = "netapp")] pub struct Opt { #[structopt(long = "network-key", short = "n")] network_key: Option, #[structopt(long = "private-key", short = "p")] private_key: Option, #[structopt(long = "bootstrap-peer", short = "b")] bootstrap_peers: Vec, #[structopt(long = "listen-addr", short = "l", default_value = "127.0.0.1:1980")] listen_addr: String, #[structopt(long = "public-addr", short = "a")] public_addr: Option, } #[tokio::main] async fn main() { env_logger::Builder::new() .parse_env("RUST_LOG") .format(|buf, record| { writeln!( buf, "{} {} {} {}", chrono::Local::now().format("%s%.6f"), record.module_path().unwrap_or("_"), record.level(), record.args() ) }) .init(); let opt = Opt::from_args(); let netid = match &opt.network_key { Some(k) => auth::Key::from_slice(&hex::decode(k).unwrap()).unwrap(), None => auth::gen_key(), }; info!("Network key: {}", hex::encode(&netid)); let privkey = match &opt.private_key { Some(k) => ed25519::SecretKey::from_slice(&hex::decode(k).unwrap()).unwrap(), None => { let (_pk, sk) = ed25519::gen_keypair(); sk } }; info!("Node private key: {}", hex::encode(&privkey)); info!("Node public key: {}", hex::encode(&privkey.public_key())); let netapp = NetApp::new(netid.clone(), privkey.clone()); let mut bootstrap_peers = vec![]; for peer in opt.bootstrap_peers.iter() { if let Some(delim) = peer.find('@') { let (key, ip) = peer.split_at(delim); let pubkey = NodeID::from_slice(&hex::decode(&key).unwrap()).unwrap(); let ip = ip[1..].parse::().unwrap(); bootstrap_peers.push((pubkey, ip)); } } let peering = FullMeshPeeringStrategy::new(netapp.clone(), bootstrap_peers); let listen_addr = opt.listen_addr.parse().unwrap(); info!("Add more peers to this mesh by running: fullmesh -n {} -l 127.0.0.1:$((1000 + $RANDOM)) -b {}@{}", hex::encode(&netid), hex::encode(&privkey.public_key()), listen_addr); let watch_cancel = netapp::util::watch_ctrl_c(); let public_addr = opt.public_addr.map(|x| x.parse().unwrap()); tokio::join!( netapp.listen(listen_addr, public_addr, watch_cancel.clone()), peering.run(watch_cancel), ); }