140 lines
5.0 KiB
Rust
140 lines
5.0 KiB
Rust
use std::{error::Error, time::Duration};
|
|
|
|
use cll2v0::messages::{MyRequest, MyResponse};
|
|
use futures::prelude::*;
|
|
use libp2p::{
|
|
mdns, noise,
|
|
request_response::{self, ProtocolSupport},
|
|
swarm::{NetworkBehaviour, SwarmEvent},
|
|
tcp, yamux, StreamProtocol, Swarm,
|
|
};
|
|
use libp2p_identity::ed25519::Keypair;
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
// We create a custom network behaviour
|
|
|
|
#[derive(NetworkBehaviour)]
|
|
struct MyBehaviour {
|
|
mdns: mdns::tokio::Behaviour,
|
|
req_res: request_response::cbor::Behaviour<MyRequest, MyResponse>,
|
|
}
|
|
|
|
fn sign(kp: &Keypair, msg: &Vec<u8>) -> String {
|
|
hex::encode(kp.sign(msg))
|
|
}
|
|
|
|
fn mk_swarm(
|
|
kp: &Keypair,
|
|
protocol_support: ProtocolSupport,
|
|
) -> Result<Swarm<MyBehaviour>, Box<dyn Error>> {
|
|
let swarm = libp2p::SwarmBuilder::with_existing_identity(kp.clone().into())
|
|
.with_tokio()
|
|
.with_tcp(
|
|
tcp::Config::default(),
|
|
noise::Config::new,
|
|
yamux::Config::default,
|
|
)?
|
|
.with_behaviour(|key| {
|
|
let mdns =
|
|
mdns::tokio::Behaviour::new(mdns::Config::default(), key.public().to_peer_id())?;
|
|
let protocol = [(StreamProtocol::new("/sign-me/1"), protocol_support)];
|
|
let config = request_response::Config::default();
|
|
let req_res =
|
|
request_response::cbor::Behaviour::<MyRequest, MyResponse>::new(protocol, config);
|
|
Ok(MyBehaviour { req_res, mdns })
|
|
})?
|
|
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX)))
|
|
.build();
|
|
Ok(swarm)
|
|
}
|
|
|
|
#[tokio::main]
|
|
pub async fn main() -> Result<(), Box<dyn Error>> {
|
|
let body: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0];
|
|
|
|
let _ = tracing_subscriber::fmt()
|
|
.with_env_filter(EnvFilter::from_default_env())
|
|
.try_init();
|
|
|
|
let keypair = libp2p_identity::ed25519::Keypair::generate();
|
|
let key = keypair.public().to_bytes();
|
|
|
|
let is_client = match std::env::args().nth(1) {
|
|
Some(arg) => {
|
|
println!("Arg {}", arg);
|
|
true
|
|
}
|
|
_ => false,
|
|
};
|
|
|
|
let protocol_support = if is_client {
|
|
ProtocolSupport::Outbound
|
|
} else {
|
|
ProtocolSupport::Inbound
|
|
};
|
|
let mut swarm = mk_swarm(&keypair, protocol_support)?;
|
|
// Tell the swarm to listen on all interfaces and a random, OS-assigned
|
|
// port.
|
|
swarm.listen_on("/ip4/192.168.1.51/tcp/0".parse()?)?;
|
|
println!("ORISIG : {}", sign(&keypair, &body));
|
|
|
|
loop {
|
|
match swarm.select_next_some().await {
|
|
SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(mdns::Event::Discovered(list))) => {
|
|
for (peer_id, multiaddr) in list {
|
|
println!("add peer {:?}, {:?}", peer_id, multiaddr.clone());
|
|
if is_client {
|
|
let _ = swarm.dial(multiaddr);
|
|
}
|
|
}
|
|
}
|
|
SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(mdns::Event::Expired(list))) => {
|
|
for (peer_id, _multiaddr) in list {
|
|
println!("mDNS discover peer has expired: {peer_id}");
|
|
// swarm.behaviour_mut().gossipsub.remove_explicit_peer(&peer_id);
|
|
}
|
|
}
|
|
SwarmEvent::Behaviour(MyBehaviourEvent::ReqRes(request_response::Event::Message {
|
|
peer: _peer,
|
|
message:
|
|
libp2p::request_response::Message::Request {
|
|
request, channel, ..
|
|
},
|
|
})) => {
|
|
// println!("Req : {:?} {:?} {:?}", peer, channel, hex::encode(request.body.clone()), );
|
|
println!("REQSIG : {}", hex::encode(request.sig.clone()),);
|
|
let _ = swarm.behaviour_mut().req_res.send_response(
|
|
channel,
|
|
MyResponse {
|
|
sig: keypair.sign(&request.body),
|
|
},
|
|
);
|
|
}
|
|
SwarmEvent::Behaviour(MyBehaviourEvent::ReqRes(request_response::Event::Message {
|
|
peer: _peer,
|
|
message: libp2p::request_response::Message::Response { response, .. },
|
|
})) => {
|
|
// println!("response : {:?} {:?} {:?}", peer, request_id, "" );
|
|
println!("RESSIG : {}", hex::encode(response.sig.clone()),);
|
|
}
|
|
SwarmEvent::ConnectionEstablished { peer_id, .. } => {
|
|
//connection_id, endpoint, num_established, concurrent_dial_errors, established_in } => {
|
|
println!("ConnectionEstablisted {}", peer_id);
|
|
if is_client {
|
|
swarm.behaviour_mut().req_res.send_request(
|
|
&peer_id,
|
|
MyRequest {
|
|
key: key.clone(),
|
|
body: body.clone(),
|
|
sig: keypair.sign(&body),
|
|
},
|
|
);
|
|
}
|
|
}
|
|
e => {
|
|
println!("OTHER {:?}", e)
|
|
}
|
|
}
|
|
}
|
|
}
|