Compare commits

...

7 Commits

Author SHA1 Message Date
mirsal 0cfc123011 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 22:59:23 +00:00
mirsal 8be534c086 Listen on IPv6 for peer discovery broadcasts
The Future
2021-03-31 21:31:04 +00:00
mirsal 5d351ebc00 Merge pull request 'Cleanup and refactor Node handling' (#4) from refactor-node into main
Reviewed-on: ryzokuken/cosmoline#4
2021-03-31 10:43:57 +00:00
Ujjwal Sharma 77387edd0d
src: rename Node and methods 2021-03-31 16:10:04 +05:30
Ujjwal Sharma 53bd1c9e6c
src: move network types to new file 2021-03-31 12:31:29 +05:30
Ujjwal Sharma 4b2a20c581
src: improve Node handling 2021-03-31 12:04:50 +05:30
Ujjwal Sharma d46faad53e
src: implement base64 handling for PublicKey 2021-03-31 12:03:48 +05:30
3 changed files with 123 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,45 @@
use clap::{load_yaml, App};
use ed25519_dalek::Keypair;
use async_std::fs;
use async_std::{fs, task};
use async_std::net::UdpSocket;
use async_std::path::PathBuf;
use async_std::sync::Arc;
use clap::{load_yaml, App};
use ed25519_dalek::Keypair;
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 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,
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();
task::sleep(std::time::Duration::from_secs(1)).await;
}
}
@ -39,10 +50,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 +70,8 @@ async fn main() {
let keypair = Keypair::read_or_generate(path.join("secret")).await;
println!("{}", keypair.to_json().pretty(2));
let socket = UdpSocket::bind("0.0.0.0: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,
}
}
}