diff --git a/Cargo.lock b/Cargo.lock
index a437247..2b925e6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -153,7 +153,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -163,7 +163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
dependencies = [
"anstyle",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -324,7 +324,7 @@ dependencies = [
"futures-lite",
"rustix",
"signal-hook",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1335,7 +1335,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -2131,6 +2131,19 @@ dependencies = [
"want",
]
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
[[package]]
name = "iana-time-zone"
version = "0.1.57"
@@ -2251,7 +2264,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"libc",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -2269,7 +2282,7 @@ dependencies = [
"hermit-abi 0.3.1",
"io-lifetimes",
"rustix",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -2580,7 +2593,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
dependencies = [
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -2610,6 +2623,24 @@ dependencies = [
"getrandom 0.2.10",
]
+[[package]]
+name = "native-tls"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
[[package]]
name = "ndk"
version = "0.6.0"
@@ -2959,6 +2990,50 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+[[package]]
+name = "openssl"
+version = "0.10.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.18",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.90"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
[[package]]
name = "ordered-float"
version = "3.7.0"
@@ -3044,10 +3119,12 @@ dependencies = [
"num_enum",
"once_cell",
"p2p-repo",
+ "reqwest",
"serde",
"serde_bare",
"serde_bytes",
"unique_id",
+ "url",
"wasm-bindgen",
]
@@ -3368,7 +3445,7 @@ dependencies = [
"libc",
"log",
"pin-project-lite",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -3710,10 +3787,12 @@ dependencies = [
"http",
"http-body",
"hyper",
+ "hyper-tls",
"ipnet",
"js-sys",
"log",
"mime",
+ "native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
@@ -3721,6 +3800,7 @@ dependencies = [
"serde_json",
"serde_urlencoded",
"tokio",
+ "tokio-native-tls",
"tokio-util",
"tower-service",
"url",
@@ -3808,7 +3888,7 @@ dependencies = [
"io-lifetimes",
"libc",
"linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -3853,6 +3933,15 @@ dependencies = [
"winapi-util",
]
+[[package]]
+name = "schannel"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
+dependencies = [
+ "windows-sys 0.42.0",
+]
+
[[package]]
name = "scoped-tls"
version = "1.0.1"
@@ -3865,6 +3954,29 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+[[package]]
+name = "security-framework"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
[[package]]
name = "selectors"
version = "0.22.0"
@@ -4605,7 +4717,7 @@ dependencies = [
"fastrand",
"redox_syscall 0.3.5",
"rustix",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -4739,7 +4851,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -4753,6 +4865,16 @@ dependencies = [
"syn 2.0.18",
]
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
[[package]]
name = "tokio-stream"
version = "0.1.14"
@@ -5059,6 +5181,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e"
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
[[package]]
name = "version-compare"
version = "0.1.1"
@@ -5480,6 +5608,21 @@ version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee78911e3f4ce32c1ad9d3c7b0bd95389662ad8d8f1a3155688fed70bd96e2b6"
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
[[package]]
name = "windows-sys"
version = "0.48.0"
diff --git a/ng-app/src/routes/WalletCreate.svelte b/ng-app/src/routes/WalletCreate.svelte
index 7ca449b..f7c8990 100644
--- a/ng-app/src/routes/WalletCreate.svelte
+++ b/ng-app/src/routes/WalletCreate.svelte
@@ -701,12 +701,13 @@
Do you trust this device?
If you do, if this device is yours or is used by few trusted persons of your
- family or workplace, then you can save your wallet in this device. To the
- contrary, if this device is public and shared by strangers, do not save your
- wallet here. {#if !import.meta.env.TAURI_PLATFORM}By selecting this
- option, you agree to save some cookies on your browser.{/if}
+ family or workplace, and you would like to login again from this device in
+ the future, then you can save your wallet on this device. To the contrary,
+ if this device is public and shared by strangers, do not save your wallet
+ here. {#if !import.meta.env.TAURI_PLATFORM}By selecting this option, you
+ agree to save some cookies on your browser.{/if}
Save your wallet here?Save your wallet on this device?
diff --git a/ng-sdk-js/src/lib.rs b/ng-sdk-js/src/lib.rs
index c6cad78..0ad84bb 100644
--- a/ng-sdk-js/src/lib.rs
+++ b/ng-sdk-js/src/lib.rs
@@ -234,8 +234,8 @@ pub async fn start() {
let x_from_ed = keys.1.to_dh_from_ed();
log_info!("Pub from X {}", x_from_ed);
- let (client_priv_key, client_pub_key) = generate_keypair();
- let (user_priv_key, user_pub_key) = generate_keypair();
+ let (client_priv, client) = generate_keypair();
+ let (user_priv, user) = generate_keypair();
log_info!("start connecting");
@@ -244,16 +244,15 @@ pub async fn start() {
.await
.connect(
Box::new(ConnectionWebSocket {}),
- IP::try_from(&IpAddr::from_str("127.0.0.1").unwrap()).unwrap(),
- WS_PORT,
- None,
keys.0,
keys.1,
server_key,
StartConfig::Client(ClientConfig {
- user: user_pub_key,
- client: client_pub_key,
- client_priv: client_priv_key,
+ url: format!("ws://127.0.0.1:{}", WS_PORT),
+ user,
+ user_priv,
+ client,
+ client_priv,
}),
)
.await;
diff --git a/p2p-broker/src/server_ws.rs b/p2p-broker/src/server_ws.rs
index 8525664..57005b5 100644
--- a/p2p-broker/src/server_ws.rs
+++ b/p2p-broker/src/server_ws.rs
@@ -276,10 +276,6 @@ fn upgrade_ws_or_serve_app(
Err(make_error(StatusCode::FORBIDDEN))
}
-const LOCAL_HOSTS: [&str; 3] = ["localhost", "127.0.0.1", "[::1]"];
-const LOCAL_URLS: [&str; 3] = ["http://localhost", "http://127.0.0.1", "http://[::1]"];
-//const APP_NG_ONE_URL: &str = "https://app.nextgraph.one";
-
impl Callback for SecurityCallback {
fn on_request(self, request: &Request) -> Result<(), ErrorResponse> {
let local_urls = LOCAL_URLS
diff --git a/p2p-client-ws/src/remote_ws.rs b/p2p-client-ws/src/remote_ws.rs
index aea4f34..95c8926 100644
--- a/p2p-client-ws/src/remote_ws.rs
+++ b/p2p-client-ws/src/remote_ws.rs
@@ -43,8 +43,7 @@ pub struct ConnectionWebSocket {}
impl IConnect for ConnectionWebSocket {
async fn open(
&self,
- ip: IP,
- port: u16,
+ url: String,
peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey,
remote_peer: DirectPeerId,
@@ -52,8 +51,6 @@ impl IConnect for ConnectionWebSocket {
) -> Result {
let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS);
- let url = format!("ws://{}:{}", ip, port);
-
let res = connect_async(url).await;
match res {
@@ -66,6 +63,7 @@ impl IConnect for ConnectionWebSocket {
let s = cnx.take_sender();
let r = cnx.take_receiver();
let mut shutdown = cnx.set_shutdown();
+ cnx.release_shutdown();
let join = task::spawn(async move {
log_debug!("START of WS loop");
@@ -103,6 +101,7 @@ impl IConnect for ConnectionWebSocket {
let s = cnx.take_sender();
let r = cnx.take_receiver();
let mut shutdown = cnx.set_shutdown();
+ cnx.release_shutdown();
let join = task::spawn(async move {
log_debug!("START of WS loop");
@@ -324,8 +323,8 @@ mod test {
let x_from_ed = keys.1.to_dh_from_ed();
log_info!("Pub from X {}", x_from_ed);
- let (client_priv_key, client_pub_key) = generate_keypair();
- let (user_priv_key, user_pub_key) = generate_keypair();
+ let (client_priv, client) = generate_keypair();
+ let (user_priv, user) = generate_keypair();
log_info!("start connecting");
{
@@ -334,13 +333,16 @@ mod test {
.await
.connect(
Box::new(ConnectionWebSocket {}),
- IP::try_from(&IpAddr::from_str("127.0.0.1").unwrap()).unwrap(),
- WS_PORT,
- None,
keys.0,
keys.1,
server_key,
- StartConfig::Probe,
+ StartConfig::Client(ClientConfig {
+ url: format!("ws://localhost:{}", WS_PORT),
+ user,
+ user_priv,
+ client,
+ client_priv,
+ }),
)
.await;
log_info!("broker.connect : {:?}", res);
diff --git a/p2p-client-ws/src/remote_ws_wasm.rs b/p2p-client-ws/src/remote_ws_wasm.rs
index 337faa7..bdecd13 100644
--- a/p2p-client-ws/src/remote_ws_wasm.rs
+++ b/p2p-client-ws/src/remote_ws_wasm.rs
@@ -37,8 +37,7 @@ pub struct ConnectionWebSocket {}
impl IConnect for ConnectionWebSocket {
async fn open(
&self,
- ip: IP,
- port: u16,
+ url: String,
peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey,
remote_peer: DirectPeerId,
@@ -46,8 +45,6 @@ impl IConnect for ConnectionWebSocket {
) -> Result {
let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS);
- let url = format!("ws://{}:{}", ip, port);
-
let (mut ws, wsio) = WsMeta::connect(url, None).await.map_err(|e| {
//log_info!("{:?}", e);
NetError::ConnectionError
diff --git a/p2p-net/Cargo.toml b/p2p-net/Cargo.toml
index b57c1ba..e6960f4 100644
--- a/p2p-net/Cargo.toml
+++ b/p2p-net/Cargo.toml
@@ -25,6 +25,8 @@ noise-protocol = "0.2.0-rc1"
noise-rust-crypto = "0.6.0-rc.1"
ed25519-dalek = "1.0.1"
either = "1.8.1"
+reqwest = { version = "0.11.18", features = ["json"] }
+url = "2.4.0"
[target.'cfg(target_arch = "wasm32")'.dependencies.getrandom]
version = "0.2.7"
diff --git a/p2p-net/src/actor.rs b/p2p-net/src/actor.rs
index 3df7978..aee3c37 100644
--- a/p2p-net/src/actor.rs
+++ b/p2p-net/src/actor.rs
@@ -121,7 +121,7 @@ impl<
match receiver.next().await {
Some(ConnectionCommand::Msg(msg)) => {
if let ProtocolMessage::BrokerMessage(ref bm) = msg {
- if bm.result() == ProtocolError::PartialContent.into()
+ if bm.result() == Into::::into(ProtocolError::PartialContent)
&& TypeId::of::() != TypeId::of::<()>()
{
let (mut b_sender, b_receiver) = mpsc::unbounded::();
@@ -141,7 +141,9 @@ impl<
actor_receiver.next().await
{
if let ProtocolMessage::BrokerMessage(ref bm) = msg {
- if bm.result() == ProtocolError::EndOfStream.into() {
+ if bm.result()
+ == Into::::into(ProtocolError::EndOfStream)
+ {
break;
}
let response = msg.try_into();
diff --git a/p2p-net/src/broker.rs b/p2p-net/src/broker.rs
index bd21132..b9be363 100644
--- a/p2p-net/src/broker.rs
+++ b/p2p-net/src/broker.rs
@@ -63,7 +63,7 @@ pub static BROKER: Lazy>> = Lazy::new(|| Arc::new(RwLock::new
pub struct Broker {
direct_connections: HashMap,
- peers: HashMap,
+ peers: HashMap,
/// (local,remote) -> ConnectionBase
anonymous_connections: HashMap<(BindAddress, BindAddress), ConnectionBase>,
#[cfg(not(target_arch = "wasm32"))]
@@ -248,7 +248,7 @@ impl Broker {
}
pub fn reconnecting(&mut self, peer_id: &DirectPeerId) {
- let peerinfo = self.peers.get_mut(peer_id);
+ let peerinfo = self.peers.get_mut(&peer_id.to_dh_slice());
match peerinfo {
Some(info) => match &info.connected {
PeerConnection::NONE => {}
@@ -264,7 +264,7 @@ impl Broker {
}
}
pub fn remove_peer_id(&mut self, peer_id: &DirectPeerId) {
- let removed = self.peers.remove(peer_id);
+ let removed = self.peers.remove(&peer_id.to_dh_slice());
match removed {
Some(info) => match info.connected {
PeerConnection::NONE => {}
@@ -285,6 +285,9 @@ impl Broker {
let removed = self
.anonymous_connections
.remove(&(local_bind_address, remote_bind_address));
+ if removed.is_some() {
+ removed.unwrap().release_shutdown();
+ }
}
pub fn test(&self) -> u32 {
@@ -363,7 +366,7 @@ impl Broker {
anonymous = Vec::from_iter(broker.anonymous_connections.keys().cloned());
}
for peer_id in peer_ids {
- BROKER.write().await.close_peer_connection(&peer_id).await;
+ BROKER.write().await.close_peer_connection_x(&peer_id).await;
}
for anon in anonymous {
BROKER.write().await.close_anonymous(anon.1, anon.0).await;
@@ -475,7 +478,7 @@ impl Broker {
lastPeerAdvert: None,
connected,
};
- self.peers.insert(remote_peer_id, bpi);
+ self.peers.insert(remote_peer_id.to_dh_slice(), bpi);
Ok(())
}
@@ -495,9 +498,6 @@ impl Broker {
pub async fn connect(
&mut self,
cnx: Box,
- ip: IP,
- port: u16,
- core: Option, // the interface used as egress for this connection
peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey,
remote_peer_id: DirectPeerId,
@@ -513,44 +513,46 @@ impl Broker {
log_info!("CONNECTING");
let mut connection = cnx
.open(
- ip,
- port,
+ config.get_url(),
Sensitive::<[u8; 32]>::from_slice(peer_privk.deref()),
peer_pubk,
remote_peer_id,
- config,
+ config.clone(),
)
.await?;
let join = connection.take_shutdown();
- let connected = if core.is_some() {
- let dc = DirectConnection {
- ip,
- interface: core.clone().unwrap(),
- remote_peer_id,
- tp: connection.transport_protocol(),
- cnx: connection,
- };
- self.direct_connections.insert(ip, dc);
- PeerConnection::Core(ip)
- } else {
- PeerConnection::Client(connection)
+ let connected = match &config {
+ StartConfig::Core(config) => {
+ let ip = config.addr.ip.clone();
+ let dc = DirectConnection {
+ ip,
+ interface: config.interface.clone(),
+ remote_peer_id,
+ tp: connection.transport_protocol(),
+ cnx: connection,
+ };
+ self.direct_connections.insert(ip, dc);
+ PeerConnection::Core(ip)
+ }
+ StartConfig::Client(config) => PeerConnection::Client(connection),
+ _ => unimplemented!(),
};
+
let bpi = BrokerPeerInfo {
lastPeerAdvert: None,
connected,
};
- self.peers.insert(remote_peer_id, bpi);
+ self.peers.insert(remote_peer_id.to_dh_slice(), bpi);
async fn watch_close(
mut join: Receiver>,
cnx: Box,
- ip: IP,
- core: Option, // the interface used as egress for this connection
peer_privk: Sensitive<[u8; 32]>,
peer_pubkey: PubKey,
remote_peer_id: DirectPeerId,
+ config: StartConfig,
) -> ResultSend<()> {
async move {
let res = join.next().await;
@@ -579,16 +581,15 @@ impl Broker {
spawn_and_log_error(watch_close(
join,
cnx,
- ip,
- core,
peer_privk,
peer_pubk,
remote_peer_id,
+ config,
));
Ok(())
}
- pub async fn close_peer_connection(&mut self, peer_id: &DirectPeerId) {
+ pub async fn close_peer_connection_x(&mut self, peer_id: &X25519PubKey) {
if let Some(peer) = self.peers.get_mut(peer_id) {
match &mut peer.connected {
PeerConnection::Core(_) => {
@@ -604,6 +605,10 @@ impl Broker {
}
}
+ pub async fn close_peer_connection(&mut self, peer_id: &DirectPeerId) {
+ self.close_peer_connection_x(&peer_id.to_dh_slice()).await
+ }
+
pub async fn close_anonymous(
&mut self,
remote_bind_address: BindAddress,
diff --git a/p2p-net/src/connection.rs b/p2p-net/src/connection.rs
index bb464dd..e8479e7 100644
--- a/p2p-net/src/connection.rs
+++ b/p2p-net/src/connection.rs
@@ -52,8 +52,7 @@ pub enum ConnectionCommand {
pub trait IConnect: Send + Sync {
async fn open(
&self,
- ip: IP,
- port: u16,
+ url: String,
peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey,
remote_peer: DirectPeerId,
@@ -144,18 +143,28 @@ pub enum StepReply {
CloseNow,
}
+#[derive(PartialEq, Debug, Clone)]
pub struct ClientConfig {
+ pub url: String,
pub user: PubKey,
+ pub user_priv: PrivKey,
pub client: PubKey,
pub client_priv: PrivKey,
}
+#[derive(PartialEq, Debug, Clone)]
pub struct ExtConfig {}
-pub struct CoreConfig {}
+#[derive(PartialEq, Debug, Clone)]
+pub struct CoreConfig {
+ pub addr: BindAddress,
+ pub interface: String,
+}
+#[derive(PartialEq, Debug, Clone)]
pub struct AdminConfig {}
+#[derive(PartialEq, Debug, Clone)]
pub enum StartConfig {
Probe,
Relay(BindAddress),
@@ -165,6 +174,16 @@ pub enum StartConfig {
Admin(AdminConfig),
}
+impl StartConfig {
+ pub fn get_url(&self) -> String {
+ match self {
+ Self::Client(config) => config.url.clone(),
+ Self::Core(config) => format!("ws://{}:{}", config.addr.ip, config.addr.port),
+ _ => unimplemented!(),
+ }
+ }
+}
+
impl NoiseFSM {
pub fn new(
bind_addresses: Option<(BindAddress, BindAddress)>,
@@ -703,10 +722,11 @@ impl ConnectionBase {
}
}
- pub async fn release_shutdown(&mut self) {
+ pub fn release_shutdown(&mut self) {
self.shutdown_sender = None;
}
+ // only used by accept
pub async fn reset_shutdown(&mut self, remote_peer_id: PubKey) {
let _ = self
.shutdown_sender
diff --git a/p2p-net/src/types.rs b/p2p-net/src/types.rs
index 635fa96..99013eb 100644
--- a/p2p-net/src/types.rs
+++ b/p2p-net/src/types.rs
@@ -88,6 +88,16 @@ pub struct BindAddress {
pub ip: IP,
}
+impl BindAddress {
+ pub fn to_ws_url(&self) -> String {
+ format!(
+ "ws://{}:{}",
+ self.ip,
+ if self.port == 0 { 80 } else { self.port }
+ )
+ }
+}
+
impl From<&SocketAddr> for BindAddress {
#[inline]
fn from(addr: &SocketAddr) -> BindAddress {
@@ -118,6 +128,162 @@ pub struct BrokerServerV0 {
pub peer_id: PubKey,
}
+pub const APP_NG_ONE_URL: &str = "https://app.nextgraph.one";
+
+pub const APP_NG_ONE_WS_URL: &str = "wss://app.nextgraph.one";
+
+fn api_dyn_peer_url(peer_id: &PubKey) -> String {
+ format!("https://nextgraph.one/api/v1/dynpeer/{}", peer_id)
+}
+
+pub const LOCAL_HOSTS: [&str; 3] = ["localhost", "127.0.0.1", "[::1]"];
+
+fn local_ws_url(port: &u16) -> String {
+ format!("ws://localhost:{}", if *port == 0 { 80 } else { *port })
+}
+
+pub const LOCAL_URLS: [&str; 3] = ["http://localhost", "http://127.0.0.1", "http://[::1]"];
+use url::{Host, Url};
+
+impl BrokerServerTypeV0 {
+ pub fn find_first_ipv4(&self) -> Option<&BindAddress> {
+ match self {
+ Self::BoxPrivate(addrs) => {
+ for addr in addrs {
+ if addr.ip.is_v4() {
+ return Some(addr);
+ }
+ }
+ return None;
+ }
+ _ => None,
+ }
+ }
+ pub fn find_first_ipv6(&self) -> Option<&BindAddress> {
+ match self {
+ Self::BoxPrivate(addrs) => {
+ for addr in addrs {
+ if addr.ip.is_v6() {
+ return Some(addr);
+ }
+ }
+ return None;
+ }
+ _ => None,
+ }
+ }
+}
+impl BrokerServerV0 {
+ fn first_ipv4(&self) -> Option<(String, Vec)> {
+ self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
+ Some((format!("ws://{}:{}", bindaddr.ip, bindaddr.port), vec![]))
+ })
+ }
+
+ fn first_ipv6(&self) -> Option<(String, Vec)> {
+ self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
+ Some((format!("ws://{}:{}", bindaddr.ip, bindaddr.port), vec![]))
+ })
+ }
+
+ /// on web browser, returns the connection URL and an optional list of BindAddress if a relay is needed
+ /// filtered by the current location url of the webpage
+ /// on native apps, returns or the connection URL without optional BindAddress or an empty string with
+ /// several BindAddresses to try to connect to with .to_ws_url()
+ pub async fn get_url(&self, location: Option) -> Option<(String, Vec)> {
+ if location.is_some() {
+ let location = location.unwrap();
+ if location.starts_with(APP_NG_ONE_URL) {
+ match &self.server_type {
+ BrokerServerTypeV0::BoxPublic(addrs) => {
+ Some((APP_NG_ONE_WS_URL.to_string(), addrs.clone()))
+ }
+ BrokerServerTypeV0::BoxPublicDyn(addrs) => {
+ let resp = reqwest::get(api_dyn_peer_url(&self.peer_id)).await;
+ if resp.is_ok() {
+ let resp = resp.unwrap().json::>().await;
+ if resp.is_ok() {
+ return Some((APP_NG_ONE_WS_URL.to_string(), resp.unwrap()));
+ }
+ }
+ if addrs.len() > 0 {
+ Some((APP_NG_ONE_WS_URL.to_string(), addrs.clone()))
+ } else {
+ None
+ }
+ }
+ _ => None,
+ }
+ } else if let BrokerServerTypeV0::Domain(domain) = &self.server_type {
+ let url = format!("https://{}", domain);
+ if location.starts_with(&url) {
+ let wss_url = format!("wss://{}", domain);
+ Some((wss_url, vec![]))
+ } else {
+ None
+ }
+ } else {
+ // localhost
+ if location.starts_with(LOCAL_URLS[0])
+ || location.starts_with(LOCAL_URLS[1])
+ || location.starts_with(LOCAL_URLS[2])
+ {
+ if let BrokerServerTypeV0::Localhost(port) = self.server_type {
+ Some((local_ws_url(&port), vec![]))
+ } else {
+ None
+ }
+ }
+ // a private address
+ else if location.starts_with("http://") {
+ let url = Url::parse(&location).unwrap();
+ match url.host() {
+ Some(Host::Ipv4(ip)) => {
+ if is_ipv4_private(&ip) {
+ self.first_ipv4()
+ } else {
+ None
+ }
+ }
+ Some(Host::Ipv6(ip)) => {
+ if is_ipv6_private(&ip) {
+ self.first_ipv6()
+ } else {
+ None
+ }
+ }
+ _ => None,
+ }
+ } else {
+ None
+ }
+ }
+ } else {
+ // From native / tauri app
+ match &self.server_type {
+ BrokerServerTypeV0::Localhost(port) => Some((local_ws_url(port), vec![])),
+ BrokerServerTypeV0::BoxPrivate(addrs) => Some((String::new(), addrs.clone())),
+ BrokerServerTypeV0::BoxPublic(addrs) => Some((String::new(), addrs.clone())),
+ BrokerServerTypeV0::BoxPublicDyn(addrs) => {
+ let resp = reqwest::get(api_dyn_peer_url(&self.peer_id)).await;
+ if resp.is_ok() {
+ let resp = resp.unwrap().json::>().await;
+ if resp.is_ok() {
+ return Some((String::new(), resp.unwrap()));
+ }
+ }
+ if addrs.len() > 0 {
+ Some((String::new(), addrs.clone()))
+ } else {
+ None
+ }
+ }
+ BrokerServerTypeV0::Domain(domain) => Some((format!("wss://{}", domain), vec![])),
+ }
+ }
+ }
+}
+
/// Bootstrap content Version 0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BootstrapContentV0 {
@@ -358,9 +524,11 @@ impl ListenerV0 {
}
}
AcceptForwardForV0::PublicDomain(_) | AcceptForwardForV0::PublicDomainPeer(_) => {
- res.push(BrokerServerTypeV0::Domain(
- self.accept_forward_for.get_domain().to_string(),
- ));
+ if !self.refuse_clients {
+ res.push(BrokerServerTypeV0::Domain(
+ self.accept_forward_for.get_domain().to_string(),
+ ));
+ }
if self.accept_direct {
if self.if_type == InterfaceType::Private {
res.push(BrokerServerTypeV0::BoxPrivate(addrs));
@@ -500,6 +668,20 @@ impl IP {
let t: &IpAddr = &self.into();
t.is_loopback()
}
+ pub fn is_v6(&self) -> bool {
+ if let Self::IPv6(_) = self {
+ true
+ } else {
+ false
+ }
+ }
+ pub fn is_v4(&self) -> bool {
+ if let Self::IPv4(_) = self {
+ true
+ } else {
+ false
+ }
+ }
}
impl fmt::Display for IP {
diff --git a/p2p-repo/src/types.rs b/p2p-repo/src/types.rs
index dd648cc..26ea068 100644
--- a/p2p-repo/src/types.rs
+++ b/p2p-repo/src/types.rs
@@ -14,7 +14,9 @@
//! Corresponds to the BARE schema
use crate::errors::NgError;
-use crate::utils::{decode_key, dh_pubkey_from_ed_slice, ed_privkey_to_pubkey};
+use crate::utils::{
+ decode_key, dh_pubkey_from_ed_slice, dh_slice_from_ed_slice, ed_privkey_to_pubkey,
+};
use core::fmt;
use serde::{Deserialize, Serialize};
use serde_bare::to_vec;
@@ -92,6 +94,9 @@ impl PubKey {
pub fn dh_from_ed_slice(slice: &[u8]) -> PubKey {
dh_pubkey_from_ed_slice(slice)
}
+ pub fn to_dh_slice(&self) -> [u8; 32] {
+ dh_slice_from_ed_slice(self.slice())
+ }
}
impl fmt::Display for PubKey {
diff --git a/p2p-repo/src/utils.rs b/p2p-repo/src/utils.rs
index da6b56f..6b21f40 100644
--- a/p2p-repo/src/utils.rs
+++ b/p2p-repo/src/utils.rs
@@ -60,12 +60,16 @@ pub fn generate_null_keypair() -> (PrivKey, PubKey) {
}
pub fn dh_pubkey_from_ed_slice(public: &[u8]) -> PubKey {
+ PubKey::X25519PubKey(dh_slice_from_ed_slice(public))
+}
+
+pub fn dh_slice_from_ed_slice(public: &[u8]) -> X25519PubKey {
let mut bits: [u8; 32] = [0u8; 32];
bits.copy_from_slice(public);
let compressed = CompressedEdwardsY(bits);
let ed_point: EdwardsPoint = compressed.decompress().unwrap();
let mon_point = ed_point.to_montgomery();
- PubKey::X25519PubKey(mon_point.to_bytes())
+ mon_point.to_bytes()
}
pub fn sign(