1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
mod behavior;
mod sm;
mod sm_behaviour;
mod storage;
pub mod subs;
mod ui_data;
use self::{sm_behaviour::SMBehaviour, storage::NetStorage, subs::key_keeper, ui_data::UiData};
use super::{ctrl, data::ipc::IPC};
use async_std::task::{self, Context, Poll};
use crossbeam::channel::{Receiver, Sender};
use futures::prelude::*;
use futures_util::StreamExt;
use libp2p::{
kad::{record::store::MemoryStore, Kademlia},
mdns::Mdns,
PeerId, Swarm,
};
use std::{self, error::Error};
pub struct Net {}
impl Net {
pub async fn lookup(
&mut self,
ui_sender: Option<Sender<ctrl::UiUpdateMsg>>,
ipc_receiver: Receiver<IPC>,
) -> Result<(), Box<dyn Error>> {
let my_peer_id = key_keeper::get_p2p_server_id();
Self::build_swarm_and_run(&my_peer_id, ui_sender, ipc_receiver).await
}
async fn build_swarm_and_run(
own_peer_id: &PeerId,
ctrl_sender: Option<Sender<ctrl::UiUpdateMsg>>,
ipc_receiver: Receiver<IPC>,
) -> Result<(), Box<dyn Error>> {
let local_key = &*key_keeper::SERVER_KEY;
let local_peer_id = PeerId::from(local_key.public());
let transport = behavior::build_noise_transport(
&*key_keeper::SERVER_KEY,
Some(*key_keeper::PRESHARED_SECRET),
);
let ui_data = UiData::new(ctrl_sender.clone());
let mut swarm = {
let store = MemoryStore::new(local_peer_id.clone());
let kademlia = Kademlia::new(local_peer_id.clone(), store);
let behaviour = behavior::AdbfBehavior {
kademlia,
mdns: Mdns::new().await?,
sm_behaviour: SMBehaviour::new(ipc_receiver, own_peer_id.clone(), ui_data),
storage: NetStorage::new(),
};
Swarm::new(transport, behaviour, local_peer_id.clone())
};
if let Some(ui_sender) = ctrl_sender {
info!("Start netsearch animation!");
ui_sender
.send(ctrl::UiUpdateMsg::CollectionUpdate(
ctrl::CollectionPathAlive::HostSearch,
ctrl::Status::ON,
))
.unwrap_or(());
}
Swarm::listen_on(&mut swarm, "/ip4/0.0.0.0/tcp/0".parse().unwrap()).unwrap();
let mut listening = false;
task::block_on(future::poll_fn(move |cx: &mut Context| {
loop {
match swarm.poll_next_unpin(cx) {
Poll::Ready(Some(_)) => info!("ha"),
Poll::Ready(None) | Poll::Pending => break,
}
}
if !listening {
for addr in libp2p::Swarm::listeners(&swarm) {
info!("Listening on {:?}", addr);
listening = true;
}
}
Poll::<()>::Pending
}));
Ok(())
}
}