Compare commits

...

6 Commits

Author SHA1 Message Date
mirsal ec43ca01c6 main: Send beacons to the all-nodes link-local multicast group 2021-03-31 21:28:44 +00:00
mirsal c59ea85329 Quick and dirty peer discovery broadcast mock implementation
* Use `async_std::task` for network loops
 * Send the generated public key over ipv4 udp broadcast frames

(peer discovery is not functional yet, although multiple instances
connected to the same link can now talk to each other, so yay.)
2021-03-31 21:28:44 +00:00
Ujjwal Sharma 7ebae99890 src: rename Node and methods 2021-03-31 21:28:44 +00:00
Ujjwal Sharma ba917197fe src: move network types to new file 2021-03-31 21:28:44 +00:00
Ujjwal Sharma 01b7f1e260 src: improve Node handling 2021-03-31 21:28:44 +00:00
Ujjwal Sharma 85efd45a88 src: implement base64 handling for PublicKey 2021-03-31 21:28:44 +00:00
3 changed files with 127 additions and 41 deletions

View File

@ -1,10 +1,25 @@
use async_std::fs;
use async_std::path::PathBuf;
use async_trait::async_trait;
use ed25519_dalek::{Keypair, PublicKey, SecretKey};
use json::{object, JsonValue};
use rand::rngs::OsRng;
use regex::Regex;
use async_std::fs;
use async_std::path::PathBuf;
use async_trait::async_trait;
pub trait SSBPublicKey {
fn to_base64(&self) -> String;
fn from_base64(string: &str) -> Self;
}
impl SSBPublicKey for PublicKey {
fn to_base64(&self) -> String {
base64::encode(self.to_bytes())
}
fn from_base64(string: &str) -> Self {
Self::from_bytes(&base64::decode(string).unwrap()).unwrap()
}
}
#[async_trait]
pub trait SSBKeypair {
@ -16,7 +31,7 @@ pub trait SSBKeypair {
#[async_trait]
impl SSBKeypair for Keypair {
fn to_json(&self) -> JsonValue {
let pubstring = base64::encode(self.public.to_bytes());
let pubstring = self.public.to_base64();
let privstring = base64::encode([self.secret.to_bytes(), self.public.to_bytes()].concat());
object! {
curve: "ed25519",
@ -36,8 +51,7 @@ impl SSBKeypair for Keypair {
.unwrap()
.strip_suffix(".ed25519")
.unwrap();
let pubkey = base64::decode(pubkey).unwrap();
let pubkey = PublicKey::from_bytes(pubkey.as_slice()).unwrap();
let pubkey = SSBPublicKey::from_base64(pubkey);
let privkey = obj["private"]
.as_str()
@ -70,7 +84,8 @@ impl SSBKeypair for Keypair {
keys = keypair_json.pretty(2),
id = keypair_json["id"]
),
).await
)
.await
.unwrap();
keypair
}

View File

@ -1,34 +1,49 @@
use async_std::{fs, task};
use async_std::net::{UdpSocket, Ipv6Addr};
use async_std::path::PathBuf;
use async_std::sync::Arc;
use clap::{load_yaml, App};
use ed25519_dalek::Keypair;
use async_std::fs;
use async_std::net::UdpSocket;
use async_std::path::PathBuf;
mod keypair;
use keypair::{SSBKeypair, SSBPublicKey};
use keypair::SSBKeypair;
mod network;
use network::Peer;
type Config = toml::map::Map<String, toml::Value>;
#[derive(Debug)]
struct Host {
protocol: String,
host: String,
port: String,
pubkey: String,
async fn peer_discovery_recv() {
let socket = UdpSocket::bind(":::8008").await.unwrap();
let all_nodes_addr = Ipv6Addr::new(0xFF02, 0, 0, 0, 0, 0, 0, 0x02);
let mut buf = [0u8; 1024];
socket.join_multicast_v6(&all_nodes_addr, 0).unwrap();
loop {
let (amt, peer) = socket.recv_from(&mut buf).await.unwrap();
let buf = &mut buf[..amt];
let packet = String::from_utf8(buf.to_vec()).unwrap();
println!(
"{} {}",
peer,
Peer::from_discovery_packet(&packet).to_discovery_packet()
);
}
}
fn parse_packet(packet: String) -> Host {
let mut packet = packet.splitn(4, ':');
let protocol = packet.next().unwrap();
let host = packet.next().unwrap();
let port = packet.next().unwrap().splitn(2, '~').next().unwrap();
let pubkey = packet.next().unwrap();
Host {
protocol: protocol.to_string(),
host: host.to_string(),
port: port.to_string(),
pubkey: pubkey.to_string(),
async fn peer_discovery_send(pubkey: Arc<String>) {
let socket = UdpSocket::bind(":::0").await.unwrap();
let msg = format!("net:1.2.3.4:8023~shs:{}", &pubkey);
let buf = msg.as_bytes();
socket.set_broadcast(true).unwrap();
loop {
println!("Sending packet: {:?}", &msg);
socket.send_to(&buf, "255.255.255.255:8008").await.unwrap();
socket.send_to(&buf, "[FF02::2]:8008").await.unwrap();
task::sleep(std::time::Duration::from_secs(1)).await;
}
}
@ -39,10 +54,12 @@ async fn main() {
let config_file = match options.value_of("config") {
Some(path) => PathBuf::from(path),
None => PathBuf::from(dirs::config_dir()
.unwrap()
.join("cosmoline")
.join("config.toml")),
None => PathBuf::from(
dirs::config_dir()
.unwrap()
.join("cosmoline")
.join("config.toml"),
),
};
let config = fs::read_to_string(config_file).await.unwrap();
let config: Config = toml::from_str(config.as_str()).unwrap();
@ -57,14 +74,8 @@ async fn main() {
let keypair = Keypair::read_or_generate(path.join("secret")).await;
println!("{}", keypair.to_json().pretty(2));
let socket = UdpSocket::bind(":::8008").await.unwrap();
let mut buf = [0u8; 1024];
loop {
let (amt, peer) = socket.recv_from(&mut buf).await.unwrap();
let buf = &mut buf[..amt];
let packet = String::from_utf8(buf.to_vec()).unwrap();
println!("{:?}", (peer, parse_packet(packet)));
};
let pubkey = keypair.public.to_base64();
task::spawn(peer_discovery_recv());
task::spawn(peer_discovery_send(Arc::new(pubkey))).await;
}

60
src/network.rs Normal file
View File

@ -0,0 +1,60 @@
use async_std::net::IpAddr;
use ed25519_dalek::PublicKey;
use crate::keypair::SSBPublicKey;
enum Protocol {
Net,
Ws,
Wss,
}
pub struct Peer {
protocol: Protocol,
host: IpAddr,
port: u16,
pubkey: PublicKey,
}
impl Peer {
pub fn to_discovery_packet(&self) -> String {
let proto = match self.protocol {
Protocol::Net => "net",
Protocol::Ws => "ws",
Protocol::Wss => "wss",
};
format!(
"{}:{}:{}~shs:{}",
proto,
self.host,
self.port,
self.pubkey.to_base64()
)
}
pub fn from_discovery_packet(packet: &str) -> Self {
let mut packet = packet.splitn(4, ':');
let protocol = match packet.next().unwrap() {
"net" => Protocol::Net,
"ws" => Protocol::Ws,
"wss" => Protocol::Wss,
_ => panic!("unknown protocol"),
};
let host = IpAddr::V4(packet.next().unwrap().parse().unwrap());
let port = packet
.next()
.unwrap()
.splitn(2, '~')
.next()
.unwrap()
.parse()
.unwrap();
let pubkey = SSBPublicKey::from_base64(packet.next().unwrap());
Peer {
protocol,
host,
port,
pubkey,
}
}
}