1use core::fmt;
15use std::collections::HashSet;
16use std::{
17 any::{Any, TypeId},
18 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
19};
20
21use serde::{Deserialize, Serialize};
22use web_time::SystemTime;
23
24use ng_repo::errors::*;
25use ng_repo::log::*;
26use ng_repo::store::Store;
27use ng_repo::types::*;
28use ng_repo::utils::{sign, verify};
29
30use crate::app_protocol::*;
31use crate::utils::{
32 get_domain_without_port_443, is_ipv4_private, is_ipv6_private, is_private_ip, is_public_ip,
33 is_public_ipv4, is_public_ipv6,
34};
35use crate::WS_PORT_ALTERNATE;
36use crate::{actor::EActor, actors::admin::*, actors::*};
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct Credentials {
41 pub user_key: PrivKey,
42 pub read_cap: ReadCap,
43 pub private_store: RepoId,
44 pub protected_store: RepoId,
45 pub public_store: RepoId,
46 pub user_master_key: SymKey,
47 pub peer_priv_key: PrivKey,
48}
49
50impl Credentials {
51 pub fn new_partial(user_priv_key: &PrivKey) -> Self {
52 Credentials {
53 user_key: user_priv_key.clone(),
54 read_cap: ReadCap::nil(),
55 private_store: RepoId::nil(),
56 protected_store: RepoId::nil(),
57 public_store: RepoId::nil(),
58 user_master_key: SymKey::random(),
59 peer_priv_key: PrivKey::random_ed(),
60 }
61 }
62}
63
64#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
69pub enum InterfaceType {
70 Loopback,
71 Private,
72 Public,
73 Invalid,
74}
75
76impl InterfaceType {
77 pub fn is_ip_valid_for_type(&self, ip: &IP) -> bool {
78 self.is_ipaddr_valid_for_type(&ip.into())
79 }
80 pub fn is_ipaddr_valid_for_type(&self, ip: &IpAddr) -> bool {
81 match ip {
82 IpAddr::V4(v4) => self.is_ipv4_valid_for_type(v4),
83 IpAddr::V6(v6) => self.is_ipv6_valid_for_type(v6),
84 }
85 }
86
87 pub fn is_ipv4_valid_for_type(&self, ip: &Ipv4Addr) -> bool {
88 match self {
89 InterfaceType::Loopback => ip.is_loopback(),
90 InterfaceType::Public => is_public_ipv4(ip),
91 InterfaceType::Private => is_ipv4_private(ip),
93 _ => false,
94 }
95 }
96 pub fn is_ipv6_valid_for_type(&self, ip: &Ipv6Addr) -> bool {
97 match self {
98 InterfaceType::Loopback => ip.is_loopback(),
99 InterfaceType::Public => is_public_ipv6(ip),
100 InterfaceType::Private => is_ipv6_private(ip),
102 _ => false,
103 }
104 }
105}
106
107#[cfg(not(target_arch = "wasm32"))]
108#[derive(Clone, Debug)]
109pub struct Interface {
110 pub if_type: InterfaceType,
111 pub name: String,
112 pub mac_addr: Option<netdev::mac::MacAddr>,
113 pub ipv4: Vec<netdev::ip::Ipv4Net>,
115 pub ipv6: Vec<netdev::ip::Ipv6Net>,
117}
118
119#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
121pub struct BindAddress {
122 pub port: u16,
123 pub ip: IP,
124}
125
126impl BindAddress {
127 pub fn to_ws_url(&self) -> String {
128 format!(
129 "ws://{}:{}",
130 self.ip,
131 if self.port == 0 { 80 } else { self.port }
132 )
133 }
134 pub fn new_localhost_with_port(port: u16) -> Self {
135 BindAddress {
136 ip: LOOPBACK_IPV4.clone(),
137 port,
138 }
139 }
140}
141
142impl From<&SocketAddr> for BindAddress {
143 #[inline]
144 fn from(addr: &SocketAddr) -> BindAddress {
145 let ip_addr = addr.ip();
146 let ip = IP::try_from(&ip_addr).unwrap();
147 let port = addr.port();
148 BindAddress { ip, port }
149 }
150}
151
152#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
158pub struct BrokerCoreV0 {
159 pub peer_id: PubKey,
161
162 pub addrs: Vec<BindAddress>,
164}
165
166#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Hash)]
168pub enum BrokerCore {
169 V0(BrokerCoreV0),
170}
171
172#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
174pub enum BrokerServerTypeV0 {
175 Localhost(u16), BoxPrivate(Vec<BindAddress>),
177 Public(Vec<BindAddress>),
178 BoxPublicDyn(Vec<BindAddress>), Domain(String), }
182
183#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
185pub struct BrokerServerV0 {
186 pub server_type: BrokerServerTypeV0,
188
189 pub can_verify: bool,
191
192 pub can_forward: bool,
194
195 pub peer_id: PubKey,
197}
198
199#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
200pub struct BrokerServerContentV0 {
201 pub servers: Vec<BrokerServerTypeV0>,
202
203 pub version: u32,
204}
205
206#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
207pub struct BrokerServer {
208 pub content: BrokerServerContentV0,
209
210 pub peer_id: PubKey,
212
213 pub sig: Option<Sig>,
215}
216
217pub type LocatorV0 = Vec<BrokerServer>;
218
219#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
220pub enum Locator {
221 V0(LocatorV0),
222}
223
224impl fmt::Display for Locator {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 let ser = serde_bare::to_vec(&self).unwrap();
227 write!(f, "{}", base64_url::encode(&ser))
228 }
229}
230
231impl Locator {
232 pub fn empty() -> Self {
233 Self::V0(vec![])
234 }
235 pub fn first_broker_server(&self) -> Result<BrokerServerV0, NgError> {
236 match self {
237 Self::V0(v0) => {
238 let bs = v0.get(0).ok_or(NgError::BrokerNotFound)?;
239 Ok(BrokerServerV0 {
240 server_type: bs
241 .content
242 .servers
243 .get(0)
244 .ok_or(NgError::BrokerNotFound)?
245 .clone(),
246 can_verify: false,
247 can_forward: false,
248 peer_id: bs.peer_id,
249 })
250 }
251 }
252 }
253 pub fn add(&mut self, bs: BrokerServerV0) {
254 match self {
255 Self::V0(v0) => {
256 for b in v0.iter_mut() {
257 if b.peer_id == bs.peer_id {
258 b.content.servers.push(bs.server_type);
259 return;
260 }
261 }
262 v0.push(BrokerServer {
263 peer_id: bs.peer_id,
264 sig: None,
265 content: BrokerServerContentV0 {
266 version: 0,
267 servers: vec![bs.server_type],
268 },
269 });
270 }
271 }
272 }
273}
274
275impl TryFrom<&str> for Locator {
276 type Error = NgError;
277 fn try_from(string: &str) -> Result<Self, NgError> {
278 let vec = base64_url::decode(string).map_err(|_| NgError::InvalidKey)?;
279 Ok(serde_bare::from_slice(&vec).map_err(|_| NgError::InvalidKey)?)
280 }
281}
282
283impl From<BrokerServerV0> for Locator {
284 fn from(bs: BrokerServerV0) -> Self {
285 Locator::V0(vec![BrokerServer {
286 peer_id: bs.peer_id,
287 content: BrokerServerContentV0 {
288 version: 0,
289 servers: vec![bs.server_type],
290 },
291 sig: None,
292 }])
293 }
294}
295
296#[doc(hidden)]
297pub const APP_ACCOUNT_REGISTERED_SUFFIX: &str = "/#/user/registered";
298
299#[doc(hidden)]
300pub const NG_NET_URL: &str = "https://nextgraph.net";
301
302#[doc(hidden)]
303pub const NG_APP_URL: &str = "https://nextgraph.app";
304
305#[doc(hidden)]
306pub const APP_NG_WS_URL: &str = "wss://nextgraph.app";
307
308#[allow(dead_code)]
309fn api_dyn_peer_url(peer_id: &PubKey) -> String {
310 format!("https://nextgraph.net/api/v1/dynpeer/{}", peer_id)
311}
312
313#[doc(hidden)]
314pub const LOCAL_HOSTS: [&str; 3] = ["localhost", "127.0.0.1", "[::1]"];
315
316fn local_ws_url(port: &u16) -> String {
317 format!("ws://localhost:{}", if *port == 0 { 80 } else { *port })
318}
319#[doc(hidden)]
320pub(crate) fn local_http_url(port: &u16) -> String {
321 format!("http://localhost:{}", if *port == 0 { 80 } else { *port })
322}
323
324#[doc(hidden)]
325pub const LOCAL_URLS: [&str; 3] = ["http://localhost", "http://127.0.0.1", "http://[::1]"];
326use url::{Host, Url};
327
328impl BrokerServerTypeV0 {
329 pub fn find_first_ipv4(&self) -> Option<&BindAddress> {
330 match self {
331 Self::BoxPrivate(addrs) => {
332 for addr in addrs {
333 if addr.ip.is_v4() {
334 return Some(addr);
335 }
336 }
337 return None;
338 }
339 _ => None,
340 }
341 }
342 pub fn find_first_ipv6(&self) -> Option<&BindAddress> {
343 match self {
344 Self::BoxPrivate(addrs) => {
345 for addr in addrs {
346 if addr.ip.is_v6() {
347 return Some(addr);
348 }
349 }
350 return None;
351 }
352 _ => None,
353 }
354 }
355}
356
357impl BrokerServerV0 {
358 pub fn new_localhost(peer_id: PubKey) -> Self {
359 BrokerServerV0 {
360 server_type: BrokerServerTypeV0::Localhost(WS_PORT_ALTERNATE[0]),
361 can_verify: false,
362 can_forward: true,
363 peer_id,
364 }
365 }
366
367 fn first_ipv4(&self) -> Option<(String, Vec<BindAddress>)> {
368 self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
369 Some((format!("ws://{}:{}", bindaddr.ip, bindaddr.port), vec![]))
370 })
371 }
372
373 fn first_ipv6(&self) -> Option<(String, Vec<BindAddress>)> {
374 self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
375 Some((format!("ws://{}:{}", bindaddr.ip, bindaddr.port), vec![]))
376 })
377 }
378
379 pub fn first_ipv4_http(&self) -> Option<String> {
380 self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
381 Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
382 })
383 }
384
385 pub fn first_ipv6_http(&self) -> Option<String> {
386 self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
387 Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
388 })
389 }
390
391 fn first_ipv6_or_ipv4(
392 ipv4: bool,
393 ipv6: bool,
394 addrs: &Vec<BindAddress>,
395 ) -> Option<&BindAddress> {
396 if ipv6 {
397 for addr in addrs {
398 if addr.ip.is_v6() {
399 return Some(addr);
400 }
401 }
402 }
403 if ipv4 {
404 for addr in addrs {
405 if addr.ip.is_v4() {
406 return Some(addr);
407 }
408 }
409 }
410 return None;
411 }
412
413 fn ng_app_bootstrap_url(addr: &BindAddress, key: PubKey) -> Option<String> {
414 let payload = (addr, key);
415 let payload_ser = serde_bare::to_vec(&payload).ok();
416 if payload_ser.is_none() {
417 return None;
418 }
419 Some(format!(
420 "{}?b={}",
421 NG_APP_URL,
422 base64_url::encode(&payload_ser.unwrap())
423 ))
424 }
425
426 fn ng_app_bootstrap_url_with_first_ipv6_or_ipv4(
427 ipv4: bool,
428 ipv6: bool,
429 addrs: &Vec<BindAddress>,
430 key: PubKey,
431 ) -> Option<String> {
432 if let Some(addr) = Self::first_ipv6_or_ipv4(ipv4, ipv6, addrs) {
433 return Self::ng_app_bootstrap_url(addr, key);
434 }
435 None
436 }
437
438 pub async fn get_url_for_ngnet(&self, ipv4: bool, ipv6: bool) -> Option<String> {
440 match &self.server_type {
441 BrokerServerTypeV0::Public(addrs) => {
442 Self::ng_app_bootstrap_url_with_first_ipv6_or_ipv4(
443 ipv4,
444 ipv6,
445 addrs,
446 self.peer_id,
447 )
448 }
449 BrokerServerTypeV0::BoxPublicDyn(addrs) => {
450 if addrs.len() > 0 {
463 Self::ng_app_bootstrap_url_with_first_ipv6_or_ipv4(
464 ipv4,
465 ipv6,
466 &addrs,
467 self.peer_id,
468 )
469 } else {
470 None
471 }
472 }
473 BrokerServerTypeV0::Domain(domain) => Some(format!("https://{}", domain)),
474 BrokerServerTypeV0::Localhost(port) => Some(local_http_url(&port)),
475 BrokerServerTypeV0::BoxPrivate(_) => {
476 if ipv6 {
477 let v6 = self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
478 Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
479 });
480 if v6.is_some() {
481 return v6;
482 }
483 }
484 if ipv4 {
485 self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
486 Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
487 })
488 } else {
489 None
490 }
491 }
492 }
493 }
494
495 pub fn is_public_server(&self) -> bool {
496 match &self.server_type {
497 BrokerServerTypeV0::Localhost(_) => false,
498 BrokerServerTypeV0::BoxPrivate(_) => false,
499 BrokerServerTypeV0::Public(_) => true,
500 BrokerServerTypeV0::BoxPublicDyn(_) => true,
501 BrokerServerTypeV0::Domain(_) => true,
502 }
503 }
504
505 pub fn get_domain(&self) -> Option<String> {
506 if let BrokerServerTypeV0::Domain(domain) = &self.server_type {
507 Some(domain.clone())
508 } else {
509 None
510 }
511 }
512
513 pub async fn get_ws_url(
518 &self,
519 location: &Option<String>,
520 ) -> Option<(String, Vec<BindAddress>)> {
521 if location.is_some() {
522 let location = location.as_ref().unwrap();
523 if location.starts_with(NG_APP_URL) {
524 match &self.server_type {
525 BrokerServerTypeV0::Public(addrs) => {
526 Some((APP_NG_WS_URL.to_string(), addrs.clone()))
527 }
528 BrokerServerTypeV0::BoxPublicDyn(addrs) => {
529 if addrs.len() > 0 {
537 Some((APP_NG_WS_URL.to_string(), addrs.clone()))
538 } else {
539 None
540 }
541 }
542 _ => None,
543 }
544 } else if let BrokerServerTypeV0::Domain(domain) = &self.server_type {
545 let url = format!("https://{}", domain);
546 if location.starts_with(&url) {
547 let wss_url = format!("wss://{}", domain);
548 Some((wss_url, vec![]))
549 } else {
550 None
551 }
552 } else {
553 if location.starts_with(LOCAL_URLS[0])
555 || location.starts_with(LOCAL_URLS[1])
556 || location.starts_with(LOCAL_URLS[2])
557 {
558 if let BrokerServerTypeV0::Localhost(port) = self.server_type {
559 Some((local_ws_url(&port), vec![]))
560 } else {
561 None
562 }
563 }
564 else if location.starts_with("http://") {
566 let url = Url::parse(&location).unwrap();
567 match url.host() {
568 Some(Host::Ipv4(ip)) => {
569 if is_ipv4_private(&ip) {
570 self.first_ipv4()
571 } else {
572 None
573 }
574 }
575 Some(Host::Ipv6(ip)) => {
576 if is_ipv6_private(&ip) {
577 self.first_ipv6()
578 } else {
579 None
580 }
581 }
582 _ => None,
583 }
584 } else {
585 None
586 }
587 }
588 } else {
589 match &self.server_type {
591 BrokerServerTypeV0::Localhost(port) => Some((local_ws_url(port), vec![])),
593 BrokerServerTypeV0::BoxPrivate(addrs) => Some((String::new(), addrs.clone())),
594 BrokerServerTypeV0::Public(addrs) => Some((String::new(), addrs.clone())),
595 BrokerServerTypeV0::BoxPublicDyn(addrs) => {
596 if addrs.len() > 0 {
604 Some((String::new(), addrs.clone()))
605 } else {
606 None
607 }
608 }
609 BrokerServerTypeV0::Domain(domain) => Some((format!("wss://{}", domain), vec![])),
610 }
611 }
612 }
613
614 pub fn to_iframe_msg(&self) -> BootstrapIframeMsg {
615
616 match &self.server_type {
617 BrokerServerTypeV0::Domain(domain) => BootstrapIframeMsg::domain(domain.clone()),
618 BrokerServerTypeV0::Localhost(port) => BootstrapIframeMsg::local(*port, self.peer_id),
619 BrokerServerTypeV0::BoxPrivate(addrs) => BootstrapIframeMsg::private(addrs.to_vec(), self.peer_id),
620 BrokerServerTypeV0::Public(_) | BrokerServerTypeV0::BoxPublicDyn(_) => BootstrapIframeMsg::ngbox(),
621 }
622 }
623}
624
625#[derive(Clone, Debug, Serialize, Deserialize)]
626pub struct BootstrapIframeMsg {
627
628 pub peer_id: Option<String>,
629
630 pub private: Option<Vec<BindAddress>>,
631
632 pub ngbox: Option<bool>,
633
634 pub domain: Option<String>,
635
636 pub localhost: Option<u16>,
637
638}
639
640impl BootstrapIframeMsg {
641 fn new() -> Self {
642 Self {
643 peer_id:None,
644 private:None,
645 ngbox:None,
646 domain:None,
647 localhost:None
648 }
649 }
650
651 fn domain(domain: String) -> Self {
652 let mut s = Self::new();
653 s.domain = Some(domain);
654 s
655 }
656
657 fn ngbox() -> Self {
658 let mut s = Self::new();
659 s.ngbox = Some(true);
660 s
661 }
662
663 fn private(addrs: Vec<BindAddress>, peer_id: PubKey) -> Self {
664 let mut s = Self::new();
665 s.peer_id = Some(peer_id.to_string());
666 s.private = Some(addrs);
667 s
668 }
669
670 fn local(port: u16, peer_id: PubKey) -> Self {
671 let mut s = Self::new();
672 s.peer_id = Some(peer_id.to_string());
673 s.localhost = Some(port);
674 s
675 }
676}
677
678#[derive(Clone, Debug, Serialize, Deserialize)]
680pub struct BootstrapContentV0 {
681 pub servers: Vec<BrokerServerV0>,
683}
684
685impl BootstrapContentV0 {
686 pub fn new_localhost(peer_id: PubKey) -> Self {
687 BootstrapContentV0 {
688 servers: vec![BrokerServerV0::new_localhost(peer_id)],
689 }
690 }
691 pub fn new_empty() -> Self {
692 BootstrapContentV0 { servers: vec![] }
693 }
694 pub fn merge(&mut self, with: &BootstrapContentV0) {
695 'outer: for server2 in &with.servers {
696 for server1 in &self.servers {
697 if *server1 == *server2 {
698 continue 'outer;
699 }
700 }
701 self.servers.push(server2.clone());
702 }
703 }
704 pub fn get_first_peer_id(&self) -> Option<PubKey> {
705 self.servers.first().map(|s| s.peer_id)
706 }
707
708 pub fn get_domain(&self) -> Option<String> {
709 for server in self.servers.iter() {
710 if let BrokerServerTypeV0::Domain(name) = &server.server_type {
711 return Some(name.clone());
712 }
713 }
714 None
715 }
716
717 pub fn to_iframe_msgs(&self) -> Vec<BootstrapIframeMsg> {
718 self.servers.iter().map(|server| server.to_iframe_msg()).collect()
719 }
720}
721
722#[derive(Clone, Debug, Serialize, Deserialize)]
723pub enum BootstrapContent {
724 V0(BootstrapContentV0),
725}
726
727impl BootstrapContent {
728 pub fn servers(&self) -> &Vec<BrokerServerV0> {
729 match self {
730 Self::V0(v0) => &v0.servers,
731 }
732 }
733}
734
735#[derive(Clone, Debug, Serialize, Deserialize)]
737pub struct LocalBootstrapInfoV0 {
738 pub bootstrap: BootstrapContentV0,
740
741 pub registration_url: Option<String>,
743}
744
745#[derive(Clone, Debug, Serialize, Deserialize)]
746pub enum LocalBootstrapInfo {
747 V0(LocalBootstrapInfoV0),
748}
749
750impl LocalBootstrapInfo {
751 pub fn servers(&self) -> &Vec<BrokerServerV0> {
752 match self {
753 Self::V0(v0) => &v0.bootstrap.servers,
754 }
755 }
756}
757
758impl From<LocalBootstrapInfo> for Invitation {
759 fn from(value: LocalBootstrapInfo) -> Self {
760 let LocalBootstrapInfo::V0(info) = value;
761 let name = info.bootstrap.get_domain();
762 let url = info.registration_url.clone();
763 Invitation::V0(InvitationV0 {
764 bootstrap: info.bootstrap,
765 code: None,
766 name,
767 url,
768 })
769 }
770}
771
772#[derive(Clone, Debug, Serialize, Deserialize)]
773pub enum InvitationCode {
774 Unique(SymKey),
775 Admin(SymKey),
776 Multi(SymKey),
777 Setup(SymKey),
778}
779
780impl InvitationCode {
781 pub fn get_symkey(&self) -> SymKey {
782 match self {
783 Self::Unique(s) | Self::Admin(s) | Self::Multi(s) | Self::Setup(s) => s.clone(),
784 }
785 }
786}
787
788impl fmt::Display for InvitationCode {
789 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790 match self {
791 Self::Unique(k) => write!(f, "unique {}", k),
792 Self::Admin(k) => write!(f, "admin {}", k),
793 Self::Multi(k) => write!(f, "multi {}", k),
794 Self::Setup(k) => write!(f, "setup {}", k),
795 }
796 }
797}
798
799#[derive(Clone, Debug, Serialize, Deserialize)]
801pub struct InvitationV0 {
802 pub bootstrap: BootstrapContentV0,
804
805 pub code: Option<SymKey>,
806
807 pub name: Option<String>,
809
810 pub url: Option<String>,
812}
813
814impl InvitationV0 {
815 pub fn set_bootstrap(&mut self, content: BootstrapContent) {
816 match content {
817 BootstrapContent::V0(v0) => self.bootstrap = v0,
818 }
819 }
820 pub fn empty(name: Option<String>) -> Self {
821 InvitationV0 {
822 bootstrap: BootstrapContentV0::new_empty(),
823 code: None,
824 name,
825 url: None,
826 }
827 }
828 pub fn new(
829 bootstrap_content: BootstrapContent,
830 code: Option<SymKey>,
831 name: Option<String>,
832 url: Option<String>,
833 ) -> Self {
834 match bootstrap_content {
835 BootstrapContent::V0(v0) => InvitationV0 {
836 bootstrap: v0,
837 code,
838 name,
839 url,
840 },
841 }
842 }
843 pub fn append_bootstraps(&mut self, add: &mut Option<BootstrapContentV0>) {
844 if add.is_some() {
845 let add = add.as_mut().unwrap();
846 self.bootstrap.servers.append(&mut add.servers);
847 }
848 }
849}
850
851impl Invitation {
852 pub fn new_v0(
853 bootstrap: BootstrapContentV0,
854 name: Option<String>,
855 url: Option<String>,
856 ) -> Self {
857 Invitation::V0(InvitationV0 {
858 bootstrap,
859 code: Some(SymKey::random()),
860 name,
861 url,
862 })
863 }
864
865 pub fn new_v0_free(
866 bootstrap: BootstrapContentV0,
867 name: Option<String>,
868 url: Option<String>,
869 ) -> Self {
870 Invitation::V0(InvitationV0 {
871 bootstrap,
872 code: None,
873 name,
874 url,
875 })
876 }
877
878 pub fn intersects(&self, invite2: Invitation) -> Invitation {
879 let Invitation::V0(v0) = self;
880 let mut new_invite = InvitationV0 {
881 bootstrap: BootstrapContentV0::new_empty(),
882 code: v0.code.clone(),
883 name: v0.name.clone(),
884 url: v0.url.clone(),
885 };
886 for server2 in invite2.get_servers() {
887 for server1 in &v0.bootstrap.servers {
888 if *server1 == *server2 {
889 new_invite.bootstrap.servers.push(server2.clone());
890 break;
891 }
892 }
893 }
894 Invitation::V0(new_invite)
895 }
896
897 pub fn get_servers(&self) -> &Vec<BrokerServerV0> {
898 match self {
899 Invitation::V0(v0) => &v0.bootstrap.servers,
900 }
901 }
902 pub fn get_domain(&self) -> Option<String> {
903 for bootstrap in self.get_servers() {
904 let res = bootstrap.get_domain();
905 if res.is_some() {
906 return res;
907 }
908 }
909 None
910 }
911
912 pub fn set_name(&mut self, name: Option<String>) {
913 if name.is_some() {
914 match self {
915 Invitation::V0(v0) => v0.name = Some(name.unwrap()),
916 }
917 }
918 }
919
920 pub fn set_url(&mut self, url: Option<&String>) {
921 if url.is_some() {
922 match self {
923 Invitation::V0(v0) => v0.url = Some(url.unwrap().clone()),
924 }
925 }
926 }
927
928 pub fn get_urls(&self) -> Vec<String> {
930 match self {
931 Invitation::V0(v0) => {
932 let mut res = vec![];
933 let ser = serde_bare::to_vec(&self).unwrap();
934 let url_param = base64_url::encode(&ser);
935 res.push(format!("{}/#/i/{}", NG_NET_URL, url_param));
936 for server in &v0.bootstrap.servers {
937 match &server.server_type {
938 BrokerServerTypeV0::Domain(domain) => {
939 res.push(format!("https://{}/#/i/{}", domain, url_param));
940 }
941 BrokerServerTypeV0::BoxPrivate(addrs) => {
942 for bindaddr in addrs {
943 res.push(format!(
944 "http://{}:{}/#/i/{}",
945 bindaddr.ip, bindaddr.port, url_param
946 ));
947 }
948 }
949 BrokerServerTypeV0::Localhost(port) => {
950 res.push(format!("{}/#/i/{}", local_http_url(&port), url_param));
951 }
952 _ => {}
953 }
954 }
955 res
956 }
957 }
958 }
959}
960
961impl fmt::Display for Invitation {
962 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
963 let ser = serde_bare::to_vec(&self).unwrap();
964 let string = base64_url::encode(&ser);
965 write!(f, "{}", string)
966 }
967}
968
969impl TryFrom<String> for Invitation {
970 type Error = NgError;
971 fn try_from(value: String) -> Result<Self, NgError> {
972 let ser = base64_url::decode(&value).map_err(|_| NgError::InvalidInvitation)?;
973 let invite: Invitation =
974 serde_bare::from_slice(&ser).map_err(|_| NgError::InvalidInvitation)?;
975 Ok(invite)
976 }
977}
978
979#[derive(Clone, Debug, Serialize, Deserialize)]
981pub enum Invitation {
982 V0(InvitationV0),
983}
984
985#[derive(Clone, Debug, Serialize, Deserialize)]
1000pub enum CreateAccountBSP {
1001 V0(CreateAccountBSPV0),
1002}
1003
1004impl TryFrom<String> for CreateAccountBSP {
1005 type Error = NgError;
1006 fn try_from(value: String) -> Result<Self, NgError> {
1007 let ser = base64_url::decode(&value).map_err(|_| NgError::InvalidCreateAccount)?;
1008 let invite: CreateAccountBSP =
1009 serde_bare::from_slice(&ser).map_err(|_| NgError::InvalidCreateAccount)?;
1010 Ok(invite)
1011 }
1012}
1013
1014impl CreateAccountBSP {
1015 pub fn encode(&self) -> Option<String> {
1016 let payload_ser = serde_bare::to_vec(self).ok();
1017 if payload_ser.is_none() {
1018 return None;
1019 }
1020 Some(base64_url::encode(&payload_ser.unwrap()))
1021 }
1022 pub fn redirect_url(&self) -> &Option<String> {
1028 match self {
1029 Self::V0(v0) => &v0.redirect_url,
1030 }
1031 }
1032 }
1043
1044#[derive(Clone, Debug, Serialize, Deserialize)]
1046pub struct CreateAccountBSPV0 {
1047 pub redirect_url: Option<String>,
1058}
1059
1060#[cfg(not(target_arch = "wasm32"))]
1062#[derive(Clone, Debug, Serialize, Deserialize)]
1063pub struct ListenerInfo {
1064 pub config: ListenerV0,
1065
1066 pub addrs: Vec<BindAddress>,
1068}
1069
1070#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
1076pub enum AcceptForwardForV0 {
1077 No,
1079
1080 PrivateDomain((String, String)),
1082
1083 PublicDomain((String, String)),
1086
1087 PublicDomainPeer((String, PrivKey, String)),
1092
1093 PublicDyn((u16, u32, String)),
1096
1097 PublicStatic((BindAddress, Option<BindAddress>, String)),
1101}
1102
1103impl AcceptForwardForV0 {
1104 pub fn get_public_bind_addresses(&self) -> Vec<BindAddress> {
1105 match self {
1106 AcceptForwardForV0::PublicStatic((ipv4, ipv6, _)) => {
1107 let mut res = vec![ipv4.clone()];
1108 if ipv6.is_some() {
1109 res.push(ipv6.unwrap().clone())
1110 }
1111 res
1112 }
1113 AcceptForwardForV0::PublicDyn(_) => {
1114 todo!();
1115 }
1116 _ => panic!("cannot call get_public_bind_addresses"),
1117 }
1118 }
1119
1120 pub fn get_public_bind_ipv6_address(&self) -> Option<IP> {
1121 match self {
1122 AcceptForwardForV0::PublicStatic((_ipv4, ipv6, _)) => {
1123 if ipv6.is_some() {
1125 return Some(ipv6.unwrap().ip.clone());
1126 } else {
1127 return None;
1128 }
1129 }
1130 AcceptForwardForV0::PublicDyn(_) => {
1131 todo!();
1132 }
1133 _ => None,
1134 }
1135 }
1136
1137 pub fn is_public_domain(&self) -> bool {
1138 match self {
1139 AcceptForwardForV0::PublicDomainPeer(_) => true,
1140 AcceptForwardForV0::PublicDomain(_) => true,
1141 _ => false,
1142 }
1143 }
1144 pub fn is_public_static(&self) -> bool {
1145 match self {
1146 AcceptForwardForV0::PublicStatic(_) => true,
1147 _ => false,
1148 }
1149 }
1150 pub fn is_no(&self) -> bool {
1151 match self {
1152 AcceptForwardForV0::No => true,
1153 _ => false,
1154 }
1155 }
1156 pub fn is_public_dyn(&self) -> bool {
1157 match self {
1158 AcceptForwardForV0::PublicDyn(_) => true,
1159 _ => false,
1160 }
1161 }
1162 pub fn is_private_domain(&self) -> bool {
1163 match self {
1164 AcceptForwardForV0::PrivateDomain(_) => true,
1165 _ => false,
1166 }
1167 }
1168 pub fn domain_with_common_peer_id(&self) -> Option<PubKey> {
1169 match self {
1170 AcceptForwardForV0::PublicDomainPeer((_, privkey, _)) => Some(privkey.to_pub()),
1171 _ => None,
1172 }
1173 }
1174 pub fn get_domain(&self) -> &str {
1175 let domain = get_domain_without_port_443(match self {
1176 AcceptForwardForV0::PrivateDomain((d, _)) => d,
1177 AcceptForwardForV0::PublicDomain((d, _)) => d,
1178 AcceptForwardForV0::PublicDomainPeer((d, _, _)) => d,
1179 _ => panic!("cannot call get_domain if AcceptForwardForV0 is not a domain"),
1180 });
1181 domain
1184 }
1185}
1186
1187#[cfg(not(target_arch = "wasm32"))]
1188#[derive(Clone, Debug, Serialize, Deserialize)]
1190pub struct ListenerV0 {
1191 pub interface_name: String,
1194
1195 pub if_type: InterfaceType,
1196
1197 pub interface_refresh: u32,
1200
1201 pub ipv6: bool,
1203
1204 pub port: u16,
1206
1207 pub private_core: bool,
1209
1210 pub serve_app: bool,
1212
1213 pub bind_public_ipv6: bool,
1215
1216 pub refuse_clients: bool,
1219
1220 pub discoverable: bool,
1222
1223 pub accept_direct: bool,
1226
1227 pub accept_forward_for: AcceptForwardForV0,
1229 }
1234
1235#[cfg(not(target_arch = "wasm32"))]
1236impl ListenerV0 {
1237 pub fn should_bind_public_ipv6_to_private_interface(&self, ip: Ipv6Addr) -> bool {
1238 let public_ip = self.accept_forward_for.get_public_bind_ipv6_address();
1239 if public_ip.is_none() {
1240 return false;
1241 }
1242 let public_ipv6addr: IpAddr = public_ip.as_ref().unwrap().into();
1243 return if let IpAddr::V6(v6) = public_ipv6addr {
1244 self.bind_public_ipv6 && self.if_type == InterfaceType::Private && ip == v6
1245 } else {
1246 false
1247 };
1248 }
1249
1250 pub fn new_direct(interface: Interface, ipv6: bool, port: u16) -> Self {
1251 Self {
1252 interface_name: interface.name,
1253 if_type: interface.if_type,
1254 interface_refresh: 0,
1255 ipv6,
1256 port,
1257 private_core: false,
1258 discoverable: false,
1259 accept_direct: true,
1260 refuse_clients: false,
1261 serve_app: true,
1262 bind_public_ipv6: false,
1263 accept_forward_for: AcceptForwardForV0::No,
1264 }
1265 }
1266
1267 pub fn is_core(&self) -> bool {
1268 match self.accept_forward_for {
1269 AcceptForwardForV0::PublicStatic(_) => true,
1270 AcceptForwardForV0::PublicDyn(_) => true,
1271 AcceptForwardForV0::PublicDomain(_) | AcceptForwardForV0::PublicDomainPeer(_) => false,
1272 AcceptForwardForV0::PrivateDomain(_) => false,
1273 AcceptForwardForV0::No => {
1274 self.if_type == InterfaceType::Public
1275 || (self.private_core && self.if_type != InterfaceType::Invalid)
1276 }
1277 }
1278 }
1279
1280 pub fn accepts_client(&self) -> bool {
1281 match self.accept_forward_for {
1282 AcceptForwardForV0::PublicStatic(_)
1283 | AcceptForwardForV0::PublicDyn(_)
1284 | AcceptForwardForV0::PublicDomain(_)
1285 | AcceptForwardForV0::PublicDomainPeer(_) => self.accept_direct || !self.refuse_clients,
1286 AcceptForwardForV0::PrivateDomain(_) => true,
1287 AcceptForwardForV0::No => {
1288 self.if_type == InterfaceType::Public && !self.refuse_clients
1289 || self.if_type != InterfaceType::Public
1290 }
1291 }
1292 }
1293
1294 pub fn get_bootstraps(&self, addrs: Vec<BindAddress>) -> Vec<BrokerServerTypeV0> {
1295 let mut res: Vec<BrokerServerTypeV0> = vec![];
1296 match self.accept_forward_for {
1297 AcceptForwardForV0::PublicStatic(_) => {
1298 let pub_addrs = self.accept_forward_for.get_public_bind_addresses();
1299 if !self.refuse_clients {
1301 res.push(BrokerServerTypeV0::Public(pub_addrs));
1302 }
1303 if self.accept_direct {
1304 res.push(BrokerServerTypeV0::BoxPrivate(addrs));
1305 }
1306 }
1307 AcceptForwardForV0::PublicDyn(_) => {
1308 let pub_addrs = self.accept_forward_for.get_public_bind_addresses();
1309 if !self.refuse_clients {
1311 res.push(BrokerServerTypeV0::BoxPublicDyn(pub_addrs));
1312 }
1313 if self.accept_direct {
1314 res.push(BrokerServerTypeV0::BoxPrivate(addrs));
1315 }
1316 }
1317 AcceptForwardForV0::PublicDomain(_) | AcceptForwardForV0::PublicDomainPeer(_) => {
1318 if !self.refuse_clients {
1319 res.push(BrokerServerTypeV0::Domain(
1320 self.accept_forward_for.get_domain().to_string(),
1321 ));
1322 }
1323 }
1332 AcceptForwardForV0::PrivateDomain(_) => {
1333 res.push(BrokerServerTypeV0::Domain(
1334 self.accept_forward_for.get_domain().to_string(),
1335 ));
1336 }
1337 AcceptForwardForV0::No => {
1338 if self.if_type == InterfaceType::Loopback {
1339 res.push(BrokerServerTypeV0::Localhost(addrs[0].port));
1340 } else if self.if_type == InterfaceType::Public {
1341 if !self.refuse_clients {
1343 res.push(BrokerServerTypeV0::Public(addrs));
1344 }
1345 } else if self.if_type == InterfaceType::Private {
1346 res.push(BrokerServerTypeV0::BoxPrivate(addrs));
1347 }
1348 }
1349 }
1350 res
1351 }
1352}
1353#[cfg(not(target_arch = "wasm32"))]
1354impl fmt::Display for ListenerV0 {
1355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1356 let mut id = self.interface_name.clone();
1357 id.push('@');
1358 id.push_str(&self.port.to_string());
1359 write!(f, "{}", id)
1360 }
1361}
1362
1363#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1365pub enum BrokerOverlayPermission {
1366 Nobody,
1367 Anybody,
1368 AllRegisteredUser,
1369 UsersList(Vec<UserId>),
1370}
1371
1372#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1374pub struct BrokerOverlayConfigV0 {
1375 pub overlays: Vec<OverlayId>,
1377 pub core: BrokerOverlayPermission,
1379 pub server: BrokerOverlayPermission,
1381 pub allow_read: bool,
1385
1386 pub forward: Vec<BrokerServerV0>,
1390}
1391
1392impl BrokerOverlayConfigV0 {
1393 pub fn new() -> Self {
1394 BrokerOverlayConfigV0 {
1395 overlays: vec![],
1396 core: BrokerOverlayPermission::Nobody,
1397 server: BrokerOverlayPermission::Nobody,
1398 allow_read: false,
1399 forward: vec![],
1400 }
1401 }
1402}
1403
1404#[derive(Clone, Debug, Serialize, Deserialize)]
1406pub enum RegistrationConfig {
1407 Closed,
1408 Invitation,
1409 Open,
1410}
1411
1412#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1416pub enum OverlayAccess {
1417 ReadOnly(OverlayId),
1421 ReadWrite((OverlayId, OverlayId)),
1425 WriteOnly(OverlayId),
1429}
1430
1431impl OverlayAccess {
1432 pub fn is_read_only(&self) -> bool {
1433 match self {
1434 Self::ReadOnly(_) => true,
1435 _ => false,
1436 }
1437 }
1438 pub fn new_write_access_from_store(store: &Store) -> OverlayAccess {
1439 match store.get_store_repo() {
1440 StoreRepo::V0(StoreRepoV0::PrivateStore(_)) | StoreRepo::V0(StoreRepoV0::Dialog(_)) => {
1441 OverlayAccess::WriteOnly(store.inner_overlay())
1442 }
1443 StoreRepo::V0(StoreRepoV0::ProtectedStore(_))
1444 | StoreRepo::V0(StoreRepoV0::Group(_))
1445 | StoreRepo::V0(StoreRepoV0::PublicStore(_)) => {
1446 OverlayAccess::ReadWrite((store.inner_overlay(), store.outer_overlay()))
1447 }
1448 }
1449 }
1450
1451 pub fn new_read_access_from_store(store: &Store) -> OverlayAccess {
1452 match store.get_store_repo() {
1453 StoreRepo::V0(StoreRepoV0::PrivateStore(_)) | StoreRepo::V0(StoreRepoV0::Dialog(_)) => {
1454 panic!("cannot get read access to a private or dialog store");
1455 }
1456 StoreRepo::V0(StoreRepoV0::ProtectedStore(_))
1457 | StoreRepo::V0(StoreRepoV0::Group(_))
1458 | StoreRepo::V0(StoreRepoV0::PublicStore(_)) => {
1459 OverlayAccess::ReadOnly(store.outer_overlay())
1460 }
1461 }
1462 }
1463
1464 pub fn new_ro(outer_overlay: OverlayId) -> Result<Self, NgError> {
1465 if let OverlayId::Outer(_digest) = outer_overlay {
1466 Ok(OverlayAccess::ReadOnly(outer_overlay))
1467 } else {
1468 Err(NgError::InvalidArgument)
1469 }
1470 }
1471 pub fn new_rw(inner_overlay: OverlayId, outer_overlay: OverlayId) -> Result<Self, NgError> {
1472 if let OverlayId::Inner(_digest) = inner_overlay {
1473 if let OverlayId::Outer(_digest) = outer_overlay {
1474 Ok(OverlayAccess::ReadWrite((inner_overlay, outer_overlay)))
1475 } else {
1476 Err(NgError::InvalidArgument)
1477 }
1478 } else {
1479 Err(NgError::InvalidArgument)
1480 }
1481 }
1482 pub fn new_wo(inner_overlay: OverlayId) -> Result<Self, NgError> {
1483 if let OverlayId::Inner(_digest) = inner_overlay {
1484 Ok(OverlayAccess::WriteOnly(inner_overlay))
1485 } else {
1486 Err(NgError::InvalidArgument)
1487 }
1488 }
1489 pub fn overlay_id_for_client_protocol_purpose(&self) -> &OverlayId {
1490 match self {
1491 Self::ReadOnly(ro) => ro,
1492 Self::ReadWrite((inner, _outer)) => inner,
1493 Self::WriteOnly(wo) => wo,
1494 }
1495 }
1496}
1497
1498#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1502pub struct InnerOverlayLink {
1503 pub id: StoreOverlay,
1505
1506 pub store_overlay_readcap: ReadCap,
1512}
1513
1514#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1518pub enum OverlayLink {
1519 Outer(Digest),
1520 InnerLink(InnerOverlayLink),
1521 Inner(Digest),
1522 Inherit,
1523 Public(PubKey),
1524 Global,
1525}
1526
1527impl OverlayLink {
1528 pub fn is_outer(&self) -> bool {
1529 match self {
1530 Self::Outer(_) => true,
1531 _ => false,
1532 }
1533 }
1534 pub fn outer(&self) -> &Digest {
1535 match self {
1536 Self::Outer(o) => o,
1537 _ => panic!("not an outer overlay ID"),
1538 }
1539 }
1540}
1541
1542impl TryFrom<OverlayLink> for OverlayId {
1543 type Error = NgError;
1544 fn try_from(link: OverlayLink) -> Result<Self, Self::Error> {
1545 Ok(match link {
1546 OverlayLink::Inner(Digest::Blake3Digest32(i)) => OverlayId::Inner(i),
1547 OverlayLink::Outer(Digest::Blake3Digest32(i)) => OverlayId::Outer(i),
1548 OverlayLink::Global => OverlayId::Global,
1549 _ => return Err(NgError::InvalidArgument),
1550 })
1551 }
1552}
1553
1554impl From<OverlayId> for OverlayLink {
1555 fn from(id: OverlayId) -> Self {
1556 match id {
1557 OverlayId::Inner(i) => OverlayLink::Inner(Digest::from_slice(i)),
1558 OverlayId::Outer(o) => OverlayLink::Outer(Digest::from_slice(o)),
1559 OverlayId::Global => OverlayLink::Global,
1560 }
1561 }
1562}
1563
1564pub type SessionId = PubKey;
1569
1570pub type ClientId = PubKey;
1572
1573pub type IPv4 = [u8; 4];
1575
1576const LOOPBACK_IPV4: IP = IP::IPv4([127, 0, 0, 1]);
1577
1578pub type IPv6 = [u8; 16];
1580
1581#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1583pub enum IP {
1584 IPv4(IPv4),
1585 IPv6(IPv6),
1586}
1587
1588impl IP {
1589 pub fn is_public(&self) -> bool {
1590 is_public_ip(&self.into())
1591 }
1592 pub fn is_private(&self) -> bool {
1593 is_private_ip(&self.into())
1594 }
1595 pub fn is_loopback(&self) -> bool {
1596 let t: &IpAddr = &self.into();
1597 t.is_loopback()
1598 }
1599 pub fn is_v6(&self) -> bool {
1600 if let Self::IPv6(_) = self {
1601 true
1602 } else {
1603 false
1604 }
1605 }
1606 pub fn is_v4(&self) -> bool {
1607 if let Self::IPv4(_) = self {
1608 true
1609 } else {
1610 false
1611 }
1612 }
1613}
1614
1615impl fmt::Display for IP {
1616 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1617 let t: IpAddr = self.try_into().unwrap();
1618 match self {
1619 IP::IPv4(_) => write!(f, "{}", t),
1620 IP::IPv6(_) => write!(f, "[{}]", t),
1621 }
1622 }
1623}
1624
1625impl From<&IpAddr> for IP {
1626 #[inline]
1627 fn from(ip: &IpAddr) -> IP {
1628 match ip {
1629 IpAddr::V4(v4) => IP::IPv4(v4.octets()),
1630 IpAddr::V6(v6) => IP::IPv6(v6.octets()),
1631 }
1632 }
1633}
1634
1635impl From<&IP> for IpAddr {
1636 #[inline]
1637 fn from(ip: &IP) -> IpAddr {
1638 match ip {
1639 IP::IPv4(v4) => IpAddr::from(*v4),
1640 IP::IPv6(v6) => IpAddr::from(*v6),
1641 }
1642 }
1643}
1644
1645#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
1647pub enum TransportProtocol {
1648 WS,
1649 QUIC,
1650 Local,
1651}
1652
1653#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
1655pub struct IPTransportAddr {
1656 pub ip: IP,
1657 pub port: u16,
1658 pub protocol: TransportProtocol,
1659}
1660
1661#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
1663pub enum NetAddr {
1664 IPTransport(IPTransportAddr),
1665}
1666
1667#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1681pub enum ClientType {
1682 Web,
1683 NativeIos,
1684 NativeAndroid,
1685 NativeMacOS,
1686 NativeLinux,
1687 NativeWin,
1688 NativeService,
1689 NodeService,
1690 Verifier,
1691 VerifierLocal,
1692 Box, Stick, WalletMaster,
1695 ClientBroker,
1696 Cli,
1697}
1698
1699#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1700pub struct ClientInfoV0 {
1701 pub client_type: ClientType,
1702 pub details: String,
1703 pub version: String,
1704 pub timestamp_install: u64,
1705 pub timestamp_updated: u64,
1706}
1707
1708#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1710pub enum ClientInfo {
1711 V0(ClientInfoV0),
1712}
1713
1714impl ClientInfo {
1715 pub fn new(client_type: ClientType, details: String, version: String) -> ClientInfo {
1716 let timestamp_install = SystemTime::now()
1717 .duration_since(SystemTime::UNIX_EPOCH)
1718 .unwrap()
1719 .as_secs();
1720 ClientInfo::V0(ClientInfoV0 {
1721 details,
1722 version,
1723 client_type,
1724 timestamp_install,
1725 timestamp_updated: timestamp_install,
1726 })
1727 }
1728}
1729
1730#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1739pub enum OverlayLeave {
1740 V0(),
1741}
1742
1743#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1747pub struct PublisherAdvertContentV0 {
1748 pub topic: TopicId,
1750
1751 pub peer: DirectPeerId,
1753}
1754
1755#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1760pub struct PublisherAdvertV0 {
1761 pub content: PublisherAdvertContentV0,
1762
1763 pub sig: Sig,
1765}
1766
1767#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1769pub enum PublisherAdvert {
1770 V0(PublisherAdvertV0),
1771}
1772
1773impl PublisherAdvert {
1774 pub fn new(
1775 topic_id: TopicId,
1776 topic_key: BranchWriteCapSecret,
1777 broker_peer: DirectPeerId,
1778 ) -> PublisherAdvert {
1779 let content = PublisherAdvertContentV0 {
1780 peer: broker_peer,
1781 topic: topic_id,
1782 };
1783 let content_ser = serde_bare::to_vec(&content).unwrap();
1784 let sig = sign(&topic_key, &topic_id, &content_ser).unwrap();
1785 PublisherAdvert::V0(PublisherAdvertV0 { content, sig })
1786 }
1787 pub fn topic_id(&self) -> &TopicId {
1788 match self {
1789 Self::V0(v0) => &v0.content.topic,
1790 }
1791 }
1792
1793 pub fn verify(&self) -> Result<(), NgError> {
1794 match self {
1795 Self::V0(v0) => verify(
1796 &serde_bare::to_vec(&v0.content).unwrap(),
1797 v0.sig,
1798 v0.content.topic,
1799 ),
1800 }
1801 }
1802
1803 pub fn verify_for_broker(&self, peer_id: &DirectPeerId) -> Result<(), ProtocolError> {
1804 match self {
1805 Self::V0(v0) => {
1806 if v0.content.peer != *peer_id {
1807 return Err(ProtocolError::InvalidPublisherAdvert);
1808 }
1809 }
1810 }
1811 Ok(self.verify()?)
1812 }
1813}
1814
1815#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1821pub struct SubReqV0 {
1822 pub topic: TopicId,
1824
1825 pub publisher: Option<DirectPeerId>,
1830}
1831
1832#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1834pub enum SubReq {
1835 V0(SubReqV0),
1836}
1837
1838#[derive(Clone, Debug, Serialize, Deserialize)]
1842pub struct SubMarkerV0 {
1843 pub publisher: DirectPeerId,
1846
1847 pub topic: TopicId,
1849
1850 pub subscriber: DirectPeerId,
1852
1853 pub known_heads: Vec<ObjectId>,
1855}
1856
1857#[derive(Clone, Debug, Serialize, Deserialize)]
1859pub enum SubMarker {
1860 V0(SubMarkerV0),
1861}
1862
1863#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1868pub struct UnsubReqV0 {
1869 pub topic: TopicId,
1871}
1872
1873#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1875pub enum UnsubReq {
1876 V0(UnsubReqV0),
1877}
1878
1879#[derive(Clone, Debug, Serialize, Deserialize)]
1887pub struct BlockSearchTopicV0 {
1888 pub topic: TopicId,
1890
1891 pub search_in_subs: bool,
1893
1894 pub ids: Vec<ObjectId>,
1896
1897 pub include_children: bool,
1899
1900 pub path: Vec<PeerId>,
1902}
1903
1904#[derive(Clone, Debug, Serialize, Deserialize)]
1906pub enum BlockSearchTopic {
1907 V0(BlockSearchTopicV0),
1908}
1909
1910#[derive(Clone, Debug, Serialize, Deserialize)]
1916pub struct BlockSearchRandomV0 {
1917 pub ids: Vec<BlockId>,
1919
1920 pub include_children: bool,
1922
1923 pub path: Vec<DirectPeerId>,
1929}
1930
1931#[derive(Clone, Debug, Serialize, Deserialize)]
1933pub enum BlockSearchRandom {
1934 V0(BlockSearchRandomV0),
1935}
1936
1937#[derive(Clone, Debug, Serialize, Deserialize)]
1941pub struct BlockResultV0 {
1942 pub payload: Vec<Block>,
1944}
1945
1946#[derive(Clone, Debug, Serialize, Deserialize)]
1950pub enum BlockResult {
1951 V0(BlockResultV0),
1952}
1953
1954#[derive(Clone, Debug, Serialize, Deserialize)]
1958pub struct TopicSyncReqV0 {
1959 pub topic: TopicId,
1961
1962 pub known_heads: Vec<ObjectId>,
1964
1965 pub target_heads: Vec<ObjectId>,
1968
1969 pub known_commits: Option<BloomFilter>,
1971
1972 #[serde(skip)]
1973 pub overlay: Option<OverlayId>,
1974}
1975
1976#[derive(Clone, Debug, Serialize, Deserialize)]
1978pub enum TopicSyncReq {
1979 V0(TopicSyncReqV0),
1980}
1981
1982impl TopicSyncReq {
1983 pub fn overlay(&self) -> &OverlayId {
1984 match self {
1985 Self::V0(v0) => v0.overlay.as_ref().unwrap(),
1986 }
1987 }
1988 pub fn set_overlay(&mut self, overlay: OverlayId) {
1989 match self {
1990 Self::V0(v0) => v0.overlay = Some(overlay),
1991 }
1992 }
1993 pub fn topic(&self) -> &TopicId {
1994 match self {
1995 TopicSyncReq::V0(o) => &o.topic,
1996 }
1997 }
1998 pub fn known_heads(&self) -> &Vec<ObjectId> {
1999 match self {
2000 TopicSyncReq::V0(o) => &o.known_heads,
2001 }
2002 }
2003 pub fn target_heads(&self) -> &Vec<ObjectId> {
2004 match self {
2005 TopicSyncReq::V0(o) => &o.target_heads,
2006 }
2007 }
2008 pub fn known_commits(&self) -> &Option<BloomFilter> {
2009 match self {
2010 TopicSyncReq::V0(o) => &o.known_commits,
2011 }
2012 }
2013}
2014
2015#[derive(Clone, Debug, Serialize, Deserialize)]
2017pub enum PeerStatus {
2018 Connected,
2019 Disconnected,
2020}
2021
2022#[derive(Clone, Debug, Serialize, Deserialize)]
2026pub struct ForwardedPeerAdvertV0 {
2027 pub peer_advert: PeerAdvertV0,
2030
2031 pub user_hash: Digest,
2035
2036 pub status: PeerStatus,
2038}
2039
2040#[derive(Clone, Debug, Serialize, Deserialize)]
2042pub enum ForwardedPeerAdvert {
2043 V0(ForwardedPeerAdvertV0),
2044}
2045
2046#[derive(Clone, Debug, Serialize, Deserialize)]
2055pub struct ForwardedPeerConflictV0 {
2056 pub advert_1: ForwardedPeerAdvertV0,
2058 pub advert_2: ForwardedPeerAdvertV0,
2060
2061 pub error_code: u16,
2062}
2063
2064#[derive(Clone, Debug, Serialize, Deserialize)]
2066pub enum ForwardedPeerConflict {
2067 V0(ForwardedPeerConflictV0),
2068}
2069
2070#[derive(Clone, Debug, Serialize, Deserialize)]
2072pub struct PeerAdvertContentV0 {
2073 pub peer: PeerId,
2075
2076 pub forwarded_by: Option<DirectPeerId>,
2078
2079 pub address: Vec<NetAddr>,
2084
2085 pub version: u32,
2087
2088 #[serde(with = "serde_bytes")]
2090 pub metadata: Vec<u8>,
2091}
2092
2093#[derive(Clone, Debug, Serialize, Deserialize)]
2100pub struct PeerAdvertV0 {
2101 pub content: PeerAdvertContentV0,
2103
2104 pub sig: Sig,
2106}
2107
2108#[derive(Clone, Debug, Serialize, Deserialize)]
2110pub enum PeerAdvert {
2111 V0(PeerAdvertV0),
2112}
2113
2114impl PeerAdvert {
2115 pub fn version(&self) -> u32 {
2116 match self {
2117 PeerAdvert::V0(o) => o.content.version,
2118 }
2119 }
2120 pub fn peer(&self) -> &PeerId {
2121 match self {
2122 PeerAdvert::V0(o) => &o.content.peer,
2123 }
2124 }
2125}
2126
2127#[derive(Clone, Debug, Serialize, Deserialize)]
2129pub enum InnerOverlayMessageContentV0 {
2130 OverlayLeave(OverlayLeave),
2131 ForwardedPeerAdvert(ForwardedPeerAdvert),
2132 ForwardedPeerConflict(ForwardedPeerConflict),
2133 PublisherJoined(PublisherAdvert),
2134 PublisherLeft(PublisherAdvert),
2135 SubReq(SubReq),
2136 SubMarker(SubMarker),
2137 UnsubReq(UnsubReq),
2138 Event(Event),
2139 }
2142
2143#[derive(Clone, Debug, Serialize, Deserialize)]
2145pub struct InnerOverlayMessagePayloadV0 {
2146 pub seq: u64,
2149
2150 pub content: InnerOverlayMessageContentV0,
2151}
2152
2153#[derive(Clone, Debug, Serialize, Deserialize)]
2155pub struct InnerOverlayMessageV0 {
2156 pub session: SessionId,
2158
2159 pub payload: InnerOverlayMessagePayloadV0,
2160
2161 pub sig: Sig,
2163
2164 #[serde(with = "serde_bytes")]
2166 pub padding: Vec<u8>,
2167}
2168
2169#[derive(Clone, Debug, Serialize, Deserialize)]
2171pub enum InnerOverlayMessage {
2172 V0(InnerOverlayMessageV0),
2173}
2174
2175#[derive(Clone, Debug, Serialize, Deserialize)]
2177pub struct OverlayAdvertPayloadV0 {
2178 pub overlay: OverlayId,
2180
2181 pub session: SessionId,
2184
2185 pub seq: u64,
2187
2188 pub publishers: Vec<PublisherAdvert>,
2193
2194 pub previous_session: Option<SessionId>,
2200
2201 pub peer: DirectPeerId,
2203}
2204
2205#[derive(Clone, Debug, Serialize, Deserialize)]
2207pub struct OverlayAdvertV0 {
2208 pub payload: OverlayAdvertPayloadV0,
2209
2210 pub sig: Sig,
2212}
2213
2214#[derive(Clone, Debug, Serialize, Deserialize)]
2216pub enum OverlayAdvert {
2217 V0(OverlayAdvertV0),
2218}
2219
2220#[derive(Clone, Debug, Serialize, Deserialize)]
2226pub struct CoreBrokerJoinedAdvertV0 {
2227 pub overlays: Vec<OverlayAdvertV0>,
2230}
2231
2232#[derive(Clone, Debug, Serialize, Deserialize)]
2237pub struct CoreBrokerLeftAdvertV0 {
2238 pub disconnected: DirectPeerId,
2240}
2241
2242#[derive(Clone, Debug, Serialize, Deserialize)]
2244pub struct CoreOverlayJoinedAdvertV0 {
2245 pub overlay: OverlayAdvertV0,
2248}
2249
2250#[derive(Clone, Debug, Serialize, Deserialize)]
2251pub enum CoreBrokerJoinedAdvert {
2252 V0(CoreBrokerJoinedAdvertV0),
2253}
2254
2255#[derive(Clone, Debug, Serialize, Deserialize)]
2256pub enum CoreBrokerLeftAdvert {
2257 V0(CoreBrokerLeftAdvertV0),
2258}
2259
2260#[derive(Clone, Debug, Serialize, Deserialize)]
2261pub enum CoreOverlayJoinedAdvert {
2262 V0(CoreOverlayJoinedAdvertV0),
2263}
2264
2265#[derive(Clone, Debug, Serialize, Deserialize)]
2267pub enum CoreAdvertContentV0 {
2268 BrokerJoined(CoreBrokerJoinedAdvert),
2269 BrokerLeft(CoreBrokerLeftAdvert),
2270 OverlayJoined(CoreOverlayJoinedAdvert),
2271}
2272
2273#[derive(Clone, Debug, Serialize, Deserialize)]
2275pub struct CoreAdvertV0 {
2276 pub content: CoreAdvertContentV0,
2277
2278 pub path: Vec<DirectPeerId>,
2281
2282 pub sig: Sig,
2284
2285 #[serde(with = "serde_bytes")]
2287 pub padding: Vec<u8>,
2288}
2289
2290#[derive(Clone, Debug, Serialize, Deserialize)]
2297pub struct OverlayAdvertMarkerV0 {
2298 pub marker: OverlayAdvertV0,
2299
2300 pub in_reply_to: SessionId,
2302
2303 pub path: Vec<DirectPeerId>,
2305
2306 pub reply_nonce: u64,
2308}
2309
2310#[derive(Clone, Debug, Serialize, Deserialize)]
2312pub struct CoreBlocksGetV0 {
2313 pub ids: Vec<BlockId>,
2315
2316 pub include_children: bool,
2318
2319 pub req_nonce: u64,
2323}
2324
2325#[derive(Clone, Debug, Serialize, Deserialize)]
2329pub struct CoreBlockResultV0 {
2330 pub payload: Vec<Block>,
2332
2333 pub req_nonce: u64,
2335}
2336
2337#[derive(Clone, Debug, Serialize, Deserialize)]
2339pub struct ReturnPathTimingAdvertV0 {
2340 pub sig: Sig,
2342
2343 pub nonce: u64,
2345}
2346
2347#[derive(Clone, Debug, Serialize, Deserialize)]
2348pub enum OverlayAdvertMarker {
2349 V0(OverlayAdvertMarkerV0),
2350}
2351
2352#[derive(Clone, Debug, Serialize, Deserialize)]
2353pub enum ReturnPathTimingAdvert {
2354 V0(ReturnPathTimingAdvertV0),
2355}
2356
2357#[derive(Clone, Debug, Serialize, Deserialize)]
2358pub enum CoreBlocksGet {
2359 V0(CoreBlocksGetV0),
2360}
2361
2362#[derive(Clone, Debug, Serialize, Deserialize)]
2363pub enum CoreBlockResult {
2364 V0(CoreBlockResultV0),
2365}
2366
2367#[derive(Clone, Debug, Serialize, Deserialize)]
2369pub enum CoreDirectMessageContentV0 {
2370 OverlayAdvertMarker(OverlayAdvertMarker),
2371 ReturnPathTimingAdvert(ReturnPathTimingAdvert),
2372 BlocksGet(CoreBlocksGet),
2373 BlockResult(CoreBlockResult),
2374 }
2378
2379#[derive(Clone, Debug, Serialize, Deserialize)]
2381pub struct CoreDirectMessageV0 {
2382 pub content: CoreDirectMessageContentV0,
2383
2384 pub reverse_path: Vec<DirectPeerId>,
2389
2390 pub from: DirectPeerId,
2392
2393 pub sig: Sig,
2395
2396 #[serde(with = "serde_bytes")]
2398 pub padding: Vec<u8>,
2399}
2400
2401#[derive(Clone, Debug, Serialize, Deserialize)]
2405pub struct CoreBrokerConnectV0 {
2406 pub inner_overlays: Vec<OverlayAdvertV0>,
2407 pub outer_overlays: Vec<Digest>,
2408}
2409
2410#[derive(Clone, Debug, Serialize, Deserialize)]
2412pub enum CoreBrokerConnect {
2413 V0(CoreBrokerConnectV0),
2414}
2415
2416#[derive(Clone, Debug, Serialize, Deserialize)]
2418pub enum CoreBrokerConnectResponse {
2419 V0(CoreBrokerConnectResponseV0),
2420}
2421
2422impl CoreBrokerConnect {
2423 pub fn core_message(&self, id: i64) -> CoreMessage {
2424 match self {
2425 CoreBrokerConnect::V0(v0) => {
2426 CoreMessage::V0(CoreMessageV0::Request(CoreRequest::V0(CoreRequestV0 {
2427 padding: vec![],
2428 id,
2429 content: CoreRequestContentV0::BrokerConnect(CoreBrokerConnect::V0(v0.clone())),
2430 })))
2431 }
2432 }
2433 }
2434}
2435
2436pub type CoreBrokerDisconnectV0 = ();
2438
2439#[derive(Clone, Debug, Serialize, Deserialize)]
2443pub enum CoreOverlayJoinV0 {
2444 Inner(OverlayAdvert),
2445 Outer(Digest),
2446}
2447
2448#[derive(Clone, Debug, Serialize, Deserialize)]
2450pub enum OuterOverlayResponseContentV0 {
2451 EmptyResponse(()),
2452 Block(Block),
2453 TopicSyncRes(TopicSyncRes),
2454 }
2456
2457#[derive(Clone, Debug, Serialize, Deserialize)]
2459pub enum OuterOverlayRequestContentV0 {
2460 TopicSyncReq(TopicSyncReq),
2461 OverlayLeave(OverlayLeave),
2462 TopicSub(PubKey),
2463 TopicUnsub(PubKey),
2464 BlocksGet(BlocksGet),
2465 }
2467
2468#[derive(Clone, Debug, Serialize, Deserialize)]
2472pub struct OuterOverlayRequestV0 {
2473 pub overlay: Digest,
2474 pub content: OuterOverlayRequestContentV0,
2475}
2476
2477#[derive(Clone, Debug, Serialize, Deserialize)]
2481pub struct OuterOverlayResponseV0 {
2482 pub overlay: Digest,
2483 pub content: OuterOverlayResponseContentV0,
2484}
2485
2486#[derive(Clone, Debug, Serialize, Deserialize)]
2497pub struct CoreTopicSyncReqV0 {
2498 pub topic: TopicId,
2500
2501 pub search_in_subs: bool,
2503
2504 pub known_heads: Vec<ObjectId>,
2506
2507 pub target_heads: Vec<ObjectId>,
2510}
2511
2512#[derive(Clone, Debug, Serialize, Deserialize)]
2514pub enum CoreTopicSyncReq {
2515 V0(CoreTopicSyncReqV0),
2516}
2517
2518#[derive(Clone, Debug, Serialize, Deserialize)]
2520pub enum TopicSyncResV0 {
2521 Event(Event),
2522 Block(Block),
2523}
2524
2525#[derive(Clone, Debug, Serialize, Deserialize)]
2529pub enum TopicSyncRes {
2530 V0(TopicSyncResV0),
2531}
2532
2533impl TopicSyncRes {
2534 pub fn event(&self) -> &Event {
2535 match self {
2536 Self::V0(TopicSyncResV0::Event(e)) => e,
2537 _ => panic!("this TopicSyncResV0 is not an event"),
2538 }
2539 }
2540}
2541
2542impl fmt::Display for TopicSyncRes {
2543 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2544 match self {
2545 Self::V0(v0) => match v0 {
2546 TopicSyncResV0::Event(e) => writeln!(f, "====== Event ====== {e}"),
2547 TopicSyncResV0::Block(b) => writeln!(f, "====== Block ID ====== {}", b.id()),
2548 },
2549 }
2550 }
2551}
2552
2553#[derive(Clone, Debug, Serialize, Deserialize)]
2554pub enum CoreBrokerDisconnect {
2555 V0(CoreBrokerDisconnectV0),
2556}
2557
2558#[derive(Clone, Debug, Serialize, Deserialize)]
2559pub enum CoreOverlayJoin {
2560 V0(CoreOverlayJoinV0),
2561}
2562
2563#[derive(Clone, Debug, Serialize, Deserialize)]
2564pub enum OuterOverlayRequest {
2565 V0(OuterOverlayRequestV0),
2566}
2567
2568#[derive(Clone, Debug, Serialize, Deserialize)]
2570pub enum CoreRequestContentV0 {
2571 BrokerConnect(CoreBrokerConnect),
2572 BrokerDisconnect(CoreBrokerDisconnect),
2573 OverlayJoin(CoreOverlayJoin),
2574 BlockSearchTopic(BlockSearchTopic),
2575 BlockSearchRandom(BlockSearchRandom),
2576 TopicSyncReq(CoreTopicSyncReq),
2577 OuterOverlayRequest(OuterOverlayRequest),
2578}
2579
2580#[derive(Clone, Debug, Serialize, Deserialize)]
2584pub struct CoreRequestV0 {
2585 pub id: i64,
2587 pub content: CoreRequestContentV0,
2588
2589 #[serde(with = "serde_bytes")]
2591 pub padding: Vec<u8>,
2592}
2593
2594#[derive(Clone, Debug, Serialize, Deserialize)]
2596pub enum CoreRequest {
2597 V0(CoreRequestV0),
2598}
2599
2600#[derive(Clone, Debug, Serialize, Deserialize)]
2604pub struct CoreBrokerConnectResponseV0 {
2605 pub successes: Vec<OverlayId>,
2606 pub errors: Vec<OverlayId>,
2607}
2608
2609#[derive(Clone, Debug, Serialize, Deserialize)]
2610pub enum OuterOverlayResponse {
2611 V0(OuterOverlayResponseV0),
2612}
2613
2614#[derive(Clone, Debug, Serialize, Deserialize)]
2616pub enum CoreResponseContentV0 {
2617 BrokerConnectResponse(CoreBrokerConnectResponse),
2618 BlockResult(BlockResult),
2619 TopicSyncRes(TopicSyncRes),
2620 OuterOverlayResponse(OuterOverlayResponse),
2621 EmptyResponse(()),
2622}
2623
2624#[derive(Clone, Debug, Serialize, Deserialize)]
2628pub struct CoreResponseV0 {
2629 pub id: i64,
2631
2632 pub result: u16,
2634 pub content: CoreResponseContentV0,
2635
2636 #[serde(with = "serde_bytes")]
2638 pub padding: Vec<u8>,
2639}
2640
2641#[derive(Clone, Debug, Serialize, Deserialize)]
2643pub enum CoreResponse {
2644 V0(CoreResponseV0),
2645}
2646
2647#[derive(Clone, Debug, Serialize, Deserialize)]
2648pub enum OuterOverlayMessageContentV0 {
2649 Event(Event),
2650}
2651
2652#[derive(Clone, Debug, Serialize, Deserialize)]
2654pub struct OuterOverlayMessageV0 {
2655 pub overlay: Digest,
2656
2657 pub content: OuterOverlayMessageContentV0,
2658
2659 #[serde(with = "serde_bytes")]
2661 pub padding: Vec<u8>,
2662}
2663
2664#[derive(Clone, Debug, Serialize, Deserialize)]
2665pub enum CoreAdvert {
2666 V0(CoreAdvertV0),
2667}
2668
2669#[derive(Clone, Debug, Serialize, Deserialize)]
2670pub enum CoreDirectMessage {
2671 V0(CoreDirectMessageV0),
2672}
2673
2674#[derive(Clone, Debug, Serialize, Deserialize)]
2675pub enum OuterOverlayMessage {
2676 V0(OuterOverlayMessageV0),
2677}
2678
2679#[derive(Clone, Debug, Serialize, Deserialize)]
2681pub enum CoreMessageV0 {
2682 Request(CoreRequest),
2683 Response(CoreResponse),
2684 Advert(CoreAdvert),
2685 Direct(CoreDirectMessage),
2686 InnerOverlay(InnerOverlayMessage),
2687 OuterOverlay(OuterOverlayMessage),
2688}
2689
2690#[derive(Clone, Debug, Serialize, Deserialize)]
2692pub enum CoreMessage {
2693 V0(CoreMessageV0),
2694}
2695
2696#[derive(Clone, Debug, Serialize, Deserialize)]
2698pub enum AppMessageContentV0 {
2699 Request(AppRequest),
2700 Response(AppResponse),
2701 SessionStop(AppSessionStop),
2702 SessionStart(AppSessionStart),
2703 EmptyResponse,
2704}
2705
2706#[derive(Clone, Debug, Serialize, Deserialize)]
2708pub struct AppMessageV0 {
2709 pub content: AppMessageContentV0,
2710
2711 pub id: i64,
2712
2713 pub result: u16,
2714}
2715
2716#[derive(Clone, Debug, Serialize, Deserialize)]
2718pub enum AppMessage {
2719 V0(AppMessageV0),
2720}
2721
2722impl IStreamable for AppMessage {
2723 fn result(&self) -> u16 {
2724 match self {
2725 AppMessage::V0(v0) => v0.result,
2726 }
2727 }
2728 fn set_result(&mut self, result: u16) {
2729 match self {
2730 AppMessage::V0(v0) => v0.result = result,
2731 }
2732 }
2733}
2734
2735impl AppMessage {
2736 pub fn get_actor(&self) -> Box<dyn EActor> {
2737 match self {
2738 AppMessage::V0(AppMessageV0 { content: o, id, .. }) => match o {
2739 AppMessageContentV0::Request(req) => req.get_actor(*id),
2740 AppMessageContentV0::SessionStop(req) => req.get_actor(*id),
2741 AppMessageContentV0::SessionStart(req) => req.get_actor(*id),
2742 AppMessageContentV0::Response(_) | AppMessageContentV0::EmptyResponse => {
2743 panic!("it is not a request");
2744 }
2745 },
2746 }
2747 }
2748 pub fn id(&self) -> Option<i64> {
2749 match self {
2750 AppMessage::V0(v0) => Some(v0.id),
2751 }
2752 }
2753 pub fn set_id(&mut self, id: i64) {
2754 match self {
2755 AppMessage::V0(r) => r.id = id,
2756 }
2757 }
2758}
2759
2760impl From<AppMessage> for ProtocolMessage {
2761 fn from(msg: AppMessage) -> ProtocolMessage {
2762 ProtocolMessage::AppMessage(msg)
2763 }
2764}
2765
2766#[derive(Clone, Debug, Serialize, Deserialize)]
2772pub enum AdminRequestContentV0 {
2773 AddUser(AddUser),
2774 DelUser(DelUser),
2775 ListUsers(ListUsers),
2776 ListInvitations(ListInvitations),
2777 AddInvitation(AddInvitation),
2778 #[doc(hidden)]
2779 CreateUser(CreateUser),
2780}
2781impl AdminRequestContentV0 {
2782 pub fn type_id(&self) -> TypeId {
2783 match self {
2784 Self::AddUser(a) => a.type_id(),
2785 Self::DelUser(a) => a.type_id(),
2786 Self::ListUsers(a) => a.type_id(),
2787 Self::ListInvitations(a) => a.type_id(),
2788 Self::AddInvitation(a) => a.type_id(),
2789 Self::CreateUser(a) => a.type_id(),
2790 }
2791 }
2792 pub fn get_actor(&self) -> Box<dyn EActor> {
2793 match self {
2794 Self::AddUser(a) => a.get_actor(),
2795 Self::DelUser(a) => a.get_actor(),
2796 Self::ListUsers(a) => a.get_actor(),
2797 Self::ListInvitations(a) => a.get_actor(),
2798 Self::AddInvitation(a) => a.get_actor(),
2799 Self::CreateUser(a) => a.get_actor(),
2800 }
2801 }
2802}
2803
2804#[derive(Clone, Debug, Serialize, Deserialize)]
2806pub struct AdminRequestV0 {
2807 pub id: i64,
2809
2810 pub content: AdminRequestContentV0,
2812
2813 pub sig: Sig,
2815
2816 pub admin_user: PubKey,
2818
2819 #[serde(with = "serde_bytes")]
2821 pub padding: Vec<u8>,
2822}
2823
2824impl AdminRequestV0 {
2825 pub fn get_actor(&self) -> Box<dyn EActor> {
2826 self.content.get_actor()
2827 }
2828}
2829
2830#[derive(Clone, Debug, Serialize, Deserialize)]
2832pub enum AdminRequest {
2833 V0(AdminRequestV0),
2834}
2835
2836impl AdminRequest {
2837 pub fn id(&self) -> i64 {
2838 match self {
2839 Self::V0(o) => o.id,
2840 }
2841 }
2842 pub fn set_id(&mut self, id: i64) {
2843 match self {
2844 Self::V0(v0) => {
2845 v0.id = id;
2846 }
2847 }
2848 }
2849 pub fn type_id(&self) -> TypeId {
2850 match self {
2851 Self::V0(o) => o.content.type_id(),
2852 }
2853 }
2854 pub fn sig(&self) -> Sig {
2855 match self {
2856 Self::V0(o) => o.sig,
2857 }
2858 }
2859 pub fn admin_user(&self) -> PubKey {
2860 match self {
2861 Self::V0(o) => o.admin_user,
2862 }
2863 }
2864 pub fn get_actor(&self) -> Box<dyn EActor> {
2865 match self {
2866 Self::V0(a) => a.get_actor(),
2867 }
2868 }
2869}
2870
2871impl From<AdminRequest> for ProtocolMessage {
2872 fn from(msg: AdminRequest) -> ProtocolMessage {
2873 ProtocolMessage::Start(StartProtocol::Admin(msg))
2874 }
2875}
2876
2877#[derive(Clone, Debug, Serialize, Deserialize)]
2879pub enum AdminResponseContentV0 {
2880 EmptyResponse,
2881 Users(Vec<PubKey>),
2882 Invitations(Vec<(InvitationCode, u32, Option<String>)>),
2883 Invitation(Invitation),
2884 UserId(UserId),
2885}
2886
2887#[derive(Clone, Debug, Serialize, Deserialize)]
2889pub struct AdminResponseV0 {
2890 pub id: i64,
2892
2893 pub result: u16,
2895
2896 pub content: AdminResponseContentV0,
2897
2898 #[serde(with = "serde_bytes")]
2900 pub padding: Vec<u8>,
2901}
2902
2903#[derive(Clone, Debug, Serialize, Deserialize)]
2905pub enum AdminResponse {
2906 V0(AdminResponseV0),
2907}
2908
2909impl From<Result<(), ProtocolError>> for AdminResponseV0 {
2910 fn from(res: Result<(), ProtocolError>) -> AdminResponseV0 {
2911 AdminResponseV0 {
2912 id: 0,
2913 result: res.map(|_| 0).unwrap_or_else(|e| e.into()),
2914 content: AdminResponseContentV0::EmptyResponse,
2915 padding: vec![],
2916 }
2917 }
2918}
2919
2920impl From<Result<PubKey, ProtocolError>> for AdminResponseV0 {
2921 fn from(res: Result<PubKey, ProtocolError>) -> AdminResponseV0 {
2922 match res {
2923 Err(e) => AdminResponseV0 {
2924 id: 0,
2925 result: e.into(),
2926 content: AdminResponseContentV0::EmptyResponse,
2927 padding: vec![],
2928 },
2929 Ok(id) => AdminResponseV0 {
2930 id: 0,
2931 result: 0,
2932 content: AdminResponseContentV0::UserId(id),
2933 padding: vec![],
2934 },
2935 }
2936 }
2937}
2938
2939impl From<Result<Vec<PubKey>, ProtocolError>> for AdminResponseV0 {
2940 fn from(res: Result<Vec<PubKey>, ProtocolError>) -> AdminResponseV0 {
2941 match res {
2942 Err(e) => AdminResponseV0 {
2943 id: 0,
2944 result: e.into(),
2945 content: AdminResponseContentV0::EmptyResponse,
2946 padding: vec![],
2947 },
2948 Ok(vec) => AdminResponseV0 {
2949 id: 0,
2950 result: 0,
2951 content: AdminResponseContentV0::Users(vec),
2952 padding: vec![],
2953 },
2954 }
2955 }
2956}
2957
2958impl From<AdminResponseV0> for ProtocolMessage {
2959 fn from(msg: AdminResponseV0) -> ProtocolMessage {
2960 ProtocolMessage::AdminResponse(AdminResponse::V0(msg))
2961 }
2962}
2963
2964impl From<AdminResponse> for ProtocolMessage {
2965 fn from(msg: AdminResponse) -> ProtocolMessage {
2966 ProtocolMessage::AdminResponse(msg)
2967 }
2968}
2969
2970impl TryFrom<ProtocolMessage> for AdminResponse {
2971 type Error = ProtocolError;
2972 fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
2973 if let ProtocolMessage::AdminResponse(res) = msg {
2974 Ok(res)
2975 } else {
2976 Err(ProtocolError::InvalidValue)
2977 }
2978 }
2979}
2980
2981impl AdminResponse {
2982 pub fn id(&self) -> i64 {
2983 match self {
2984 Self::V0(o) => o.id,
2985 }
2986 }
2987 pub fn set_id(&mut self, id: i64) {
2988 match self {
2989 Self::V0(v0) => {
2990 v0.id = id;
2991 }
2992 }
2993 }
2994 pub fn result(&self) -> u16 {
2995 match self {
2996 Self::V0(o) => o.result,
2997 }
2998 }
2999 pub fn content_v0(&self) -> AdminResponseContentV0 {
3000 match self {
3001 Self::V0(o) => o.content.clone(),
3002 }
3003 }
3004}
3005
3006#[derive(Clone, Debug, Serialize, Deserialize)]
3016pub struct OpenRepoV0 {
3017 pub hash: RepoHash,
3019
3020 pub overlay: OverlayAccess,
3022
3023 pub peers: Vec<PeerAdvert>,
3028
3029 pub max_peer_count: u16,
3037
3038 pub ro_topics: Vec<TopicId>,
3040
3041 pub rw_topics: Vec<PublisherAdvert>,
3045}
3046
3047#[derive(Clone, Debug, Serialize, Deserialize)]
3049pub enum OpenRepo {
3050 V0(OpenRepoV0),
3051}
3052
3053impl OpenRepo {
3054 pub fn peers(&self) -> &Vec<PeerAdvert> {
3055 match self {
3056 OpenRepo::V0(o) => &o.peers,
3057 }
3058 }
3059}
3060
3061#[derive(Clone, Debug, Serialize, Deserialize)]
3066pub struct PinRepoV0 {
3067 pub hash: RepoHash,
3069
3070 pub overlay: OverlayAccess,
3072
3073 pub overlay_root_topic: Option<TopicId>,
3075
3076 pub expose_outer: bool,
3078
3079 pub peers: Vec<PeerAdvert>,
3083
3084 pub max_peer_count: u16,
3086
3087 pub ro_topics: Vec<TopicId>,
3096
3097 pub rw_topics: Vec<PublisherAdvert>,
3101 }
3104
3105#[derive(Clone, Debug, Serialize, Deserialize)]
3107pub enum PinRepo {
3108 V0(PinRepoV0),
3109}
3110
3111impl PinRepo {
3112 pub fn peers(&self) -> &Vec<PeerAdvert> {
3113 match self {
3114 PinRepo::V0(o) => &o.peers,
3115 }
3116 }
3117 pub fn hash(&self) -> &RepoHash {
3118 match self {
3119 PinRepo::V0(o) => &o.hash,
3120 }
3121 }
3122 pub fn ro_topics(&self) -> &Vec<TopicId> {
3123 match self {
3124 PinRepo::V0(o) => &o.ro_topics,
3125 }
3126 }
3127 pub fn rw_topics(&self) -> &Vec<PublisherAdvert> {
3128 match self {
3129 PinRepo::V0(o) => &o.rw_topics,
3130 }
3131 }
3132 pub fn overlay(&self) -> &OverlayId {
3133 match self {
3134 PinRepo::V0(o) => &o.overlay.overlay_id_for_client_protocol_purpose(),
3135 }
3136 }
3137 pub fn overlay_access(&self) -> &OverlayAccess {
3138 match self {
3139 PinRepo::V0(o) => &o.overlay,
3140 }
3141 }
3142
3143 pub fn overlay_root_topic(&self) -> &Option<TopicId> {
3144 match self {
3145 PinRepo::V0(o) => &o.overlay_root_topic,
3146 }
3147 }
3148
3149 pub fn expose_outer(&self) -> bool {
3150 match self {
3151 PinRepo::V0(o) => o.expose_outer,
3152 }
3153 }
3154}
3155
3156#[derive(Clone, Debug, Serialize, Deserialize)]
3161pub struct RefreshPinRepoV0 {
3162 pub pin: PinRepo,
3164
3165 pub ban_member: Option<Digest>,
3167
3168 pub flush_topics: Vec<(TopicId, Sig)>,
3178}
3179
3180#[derive(Clone, Debug, Serialize, Deserialize)]
3182pub enum RefreshPinRepo {
3183 V0(RefreshPinRepoV0),
3184}
3185
3186#[derive(Clone, Debug, Serialize, Deserialize)]
3192pub struct UnpinRepoV0 {
3193 pub hash: RepoHash,
3195}
3196
3197#[derive(Clone, Debug, Serialize, Deserialize)]
3199pub enum UnpinRepo {
3200 V0(UnpinRepoV0),
3201}
3202
3203impl UnpinRepo {
3204 pub fn hash(&self) -> &RepoHash {
3205 match self {
3206 UnpinRepo::V0(o) => &o.hash,
3207 }
3208 }
3209}
3210
3211#[derive(Clone, Debug, Serialize, Deserialize)]
3217pub struct RepoPinStatusReqV0 {
3218 pub hash: RepoHash,
3220
3221 #[serde(skip)]
3222 pub overlay: Option<OverlayId>,
3223}
3224
3225#[derive(Clone, Debug, Serialize, Deserialize)]
3227pub enum RepoPinStatusReq {
3228 V0(RepoPinStatusReqV0),
3229}
3230
3231impl RepoPinStatusReq {
3232 pub fn hash(&self) -> &RepoHash {
3233 match self {
3234 RepoPinStatusReq::V0(o) => &o.hash,
3235 }
3236 }
3237 pub fn set_overlay(&mut self, overlay: OverlayId) {
3238 match self {
3239 Self::V0(v0) => v0.overlay = Some(overlay),
3240 }
3241 }
3242
3243 pub fn overlay(&self) -> &OverlayId {
3244 match self {
3245 Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3246 }
3247 }
3248}
3249
3250#[derive(Clone, Debug, Serialize, Deserialize)]
3252pub struct RepoPinStatusV0 {
3253 pub hash: RepoHash,
3255
3256 pub expose_outer: bool,
3258
3259 pub topics: Vec<TopicSubRes>,
3261 }
3265
3266#[derive(Clone, Debug, Serialize, Deserialize)]
3268pub enum RepoPinStatus {
3269 V0(RepoPinStatusV0),
3270}
3271
3272impl RepoPinStatus {
3273 pub fn hash(&self) -> &RepoHash {
3274 match self {
3275 RepoPinStatus::V0(o) => &o.hash,
3276 }
3277 }
3278 pub fn is_topic_subscribed_as_publisher(&self, topic: &TopicId) -> bool {
3279 match self {
3280 Self::V0(v0) => {
3281 for sub in &v0.topics {
3282 if sub.topic_id() == topic {
3283 return sub.is_publisher();
3284 }
3285 }
3286 false
3287 }
3288 }
3289 }
3290 pub fn topics(&self) -> &Vec<TopicSubRes> {
3291 match self {
3292 Self::V0(v0) => &v0.topics,
3293 }
3294 }
3295}
3296
3297#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3301pub struct TopicSubV0 {
3302 pub topic: TopicId,
3304
3305 pub repo_hash: RepoHash,
3307
3308 pub publisher: Option<PublisherAdvert>,
3310
3311 #[serde(skip)]
3312 pub overlay: Option<OverlayId>,
3313}
3314
3315#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3317pub enum TopicSub {
3318 V0(TopicSubV0),
3319}
3320
3321impl TopicSub {
3322 pub fn hash(&self) -> &RepoHash {
3323 match self {
3324 Self::V0(o) => &o.repo_hash,
3325 }
3326 }
3327 pub fn topic(&self) -> &TopicId {
3328 match self {
3329 Self::V0(o) => &o.topic,
3330 }
3331 }
3332 pub fn publisher(&self) -> Option<&PublisherAdvert> {
3333 match self {
3334 Self::V0(o) => o.publisher.as_ref(),
3335 }
3336 }
3337 pub fn set_overlay(&mut self, overlay: OverlayId) {
3338 match self {
3339 Self::V0(v0) => v0.overlay = Some(overlay),
3340 }
3341 }
3342 pub fn overlay(&self) -> &OverlayId {
3343 match self {
3344 Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3345 }
3346 }
3347}
3348
3349#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3351pub struct TopicUnsubV0 {
3352 pub topic: PubKey,
3354
3355 pub repo_hash: RepoHash,
3357}
3358
3359#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3361pub enum TopicUnsub {
3362 V0(TopicUnsubV0),
3363}
3364
3365#[derive(Clone, Debug, Serialize, Deserialize)]
3369pub struct BlocksGetV0 {
3370 pub ids: Vec<BlockId>,
3372
3373 pub include_children: bool,
3375
3376 pub topic: Option<TopicId>,
3379
3380 #[serde(skip)]
3381 pub overlay: Option<OverlayId>,
3382}
3383
3384#[derive(Clone, Debug, Serialize, Deserialize)]
3386pub enum BlocksGet {
3387 V0(BlocksGetV0),
3388}
3389
3390impl BlocksGet {
3391 pub fn ids(&self) -> &Vec<BlockId> {
3392 match self {
3393 BlocksGet::V0(o) => &o.ids,
3394 }
3395 }
3396 pub fn include_children(&self) -> bool {
3397 match self {
3398 BlocksGet::V0(o) => o.include_children,
3399 }
3400 }
3401 pub fn topic(&self) -> Option<PubKey> {
3402 match self {
3403 BlocksGet::V0(o) => o.topic,
3404 }
3405 }
3406}
3407
3408#[derive(Clone, Debug, Serialize, Deserialize)]
3416pub struct CommitGetV0 {
3417 pub id: ObjectId,
3419
3420 pub topic: Option<TopicId>,
3423
3424 #[serde(skip)]
3425 pub overlay: Option<OverlayId>,
3426}
3427
3428#[derive(Clone, Debug, Serialize, Deserialize)]
3430pub enum CommitGet {
3431 V0(CommitGetV0),
3432}
3433impl CommitGet {
3434 pub fn id(&self) -> &ObjectId {
3435 match self {
3436 CommitGet::V0(o) => &o.id,
3437 }
3438 }
3439}
3440
3441#[derive(Clone, Debug, Serialize, Deserialize)]
3443pub struct WalletPutExportV0 {
3444 pub wallet: ExportedWallet,
3445 pub rendezvous_id: SymKey,
3446 pub is_rendezvous: bool,
3447}
3448
3449#[derive(Clone, Debug, Serialize, Deserialize)]
3451pub enum WalletPutExport {
3452 V0(WalletPutExportV0),
3453}
3454
3455#[derive(Clone, Debug, Serialize, Deserialize)]
3457pub struct BlocksPutV0 {
3458 pub blocks: Vec<Block>,
3460
3461 #[serde(skip)]
3462 pub overlay: Option<OverlayId>,
3463}
3464
3465#[derive(Clone, Debug, Serialize, Deserialize)]
3467pub enum BlocksPut {
3468 V0(BlocksPutV0),
3469}
3470
3471impl BlocksPut {
3472 pub fn blocks(&self) -> &Vec<Block> {
3473 match self {
3474 BlocksPut::V0(o) => &o.blocks,
3475 }
3476 }
3477 pub fn overlay(&self) -> &OverlayId {
3478 match self {
3479 Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3480 }
3481 }
3482 pub fn set_overlay(&mut self, overlay: OverlayId) {
3483 match self {
3484 Self::V0(v0) => v0.overlay = Some(overlay),
3485 }
3486 }
3487}
3488
3489#[derive(Clone, Debug, Serialize, Deserialize)]
3493pub struct BlocksExistV0 {
3494 pub blocks: Vec<BlockId>,
3496
3497 #[serde(skip)]
3498 pub overlay: Option<OverlayId>,
3499}
3500
3501#[derive(Clone, Debug, Serialize, Deserialize)]
3503pub enum BlocksExist {
3504 V0(BlocksExistV0),
3505}
3506
3507impl BlocksExist {
3508 pub fn blocks(&self) -> &Vec<BlockId> {
3509 match self {
3510 BlocksExist::V0(o) => &o.blocks,
3511 }
3512 }
3513 pub fn overlay(&self) -> &OverlayId {
3514 match self {
3515 Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3516 }
3517 }
3518 pub fn set_overlay(&mut self, overlay: OverlayId) {
3519 match self {
3520 Self::V0(v0) => v0.overlay = Some(overlay),
3521 }
3522 }
3523}
3524
3525#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3531pub struct ObjectPinV0 {
3532 pub id: ObjectId,
3533}
3534
3535#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3537pub enum ObjectPin {
3538 V0(ObjectPinV0),
3539}
3540
3541impl ObjectPin {
3542 pub fn id(&self) -> ObjectId {
3543 match self {
3544 ObjectPin::V0(o) => o.id,
3545 }
3546 }
3547}
3548
3549#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3551pub struct ObjectUnpinV0 {
3552 pub id: ObjectId,
3553}
3554
3555#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3557pub enum ObjectUnpin {
3558 V0(ObjectUnpinV0),
3559}
3560
3561impl ObjectUnpin {
3562 pub fn id(&self) -> ObjectId {
3563 match self {
3564 ObjectUnpin::V0(o) => o.id,
3565 }
3566 }
3567}
3568
3569#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3573pub struct ObjectDelV0 {
3574 pub id: ObjectId,
3575}
3576
3577#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3579pub enum ObjectDel {
3580 V0(ObjectDelV0),
3581}
3582
3583impl ObjectDel {
3584 pub fn id(&self) -> ObjectId {
3585 match self {
3586 ObjectDel::V0(o) => o.id,
3587 }
3588 }
3589}
3590
3591#[derive(Clone, Debug, Serialize, Deserialize)]
3593pub struct PublishEvent(pub Event, #[serde(skip)] pub Option<OverlayId>);
3594
3595#[derive(Clone, Debug, Serialize, Deserialize)]
3597pub enum ClientRequestContentV0 {
3598 OpenRepo(OpenRepo),
3599 PinRepo(PinRepo),
3600 UnpinRepo(UnpinRepo),
3601 RepoPinStatusReq(RepoPinStatusReq),
3602
3603 TopicSub(TopicSub),
3605 TopicUnsub(TopicUnsub),
3606
3607 BlocksExist(BlocksExist),
3608 BlocksGet(BlocksGet),
3609 CommitGet(CommitGet),
3610 TopicSyncReq(TopicSyncReq),
3611
3612 ObjectPin(ObjectPin),
3614 ObjectUnpin(ObjectUnpin),
3615 ObjectDel(ObjectDel),
3616
3617 BlocksPut(BlocksPut),
3619 PublishEvent(PublishEvent),
3620
3621 WalletPutExport(WalletPutExport),
3622}
3623
3624impl ClientRequestContentV0 {
3625 pub fn set_overlay(&mut self, overlay: OverlayId) {
3626 match self {
3627 ClientRequestContentV0::RepoPinStatusReq(a) => a.set_overlay(overlay),
3628 ClientRequestContentV0::TopicSub(a) => a.set_overlay(overlay),
3629 ClientRequestContentV0::PinRepo(_a) => {}
3630 ClientRequestContentV0::PublishEvent(a) => a.set_overlay(overlay),
3631 ClientRequestContentV0::CommitGet(a) => a.set_overlay(overlay),
3632 ClientRequestContentV0::TopicSyncReq(a) => a.set_overlay(overlay),
3633 ClientRequestContentV0::BlocksPut(a) => a.set_overlay(overlay),
3634 ClientRequestContentV0::BlocksExist(a) => a.set_overlay(overlay),
3635 ClientRequestContentV0::BlocksGet(a) => a.set_overlay(overlay),
3636 ClientRequestContentV0::WalletPutExport(_a) => {}
3637 _ => unimplemented!(),
3638 }
3639 }
3640}
3641
3642#[derive(Clone, Debug, Serialize, Deserialize)]
3644pub struct ClientRequestV0 {
3645 pub id: i64,
3647
3648 pub content: ClientRequestContentV0,
3650}
3651
3652#[derive(Clone, Debug, Serialize, Deserialize)]
3654pub enum ClientRequest {
3655 V0(ClientRequestV0),
3656}
3657
3658impl ClientRequest {
3659 pub fn id(&self) -> i64 {
3660 match self {
3661 ClientRequest::V0(o) => o.id,
3662 }
3663 }
3664 pub fn set_id(&mut self, id: i64) {
3665 match self {
3666 ClientRequest::V0(v0) => {
3667 v0.id = id;
3668 }
3669 }
3670 }
3671 pub fn content_v0(&self) -> &ClientRequestContentV0 {
3672 match self {
3673 ClientRequest::V0(o) => &o.content,
3674 }
3675 }
3676 pub fn get_actor(&self) -> Box<dyn EActor> {
3677 match self {
3678 Self::V0(ClientRequestV0 { content, .. }) => match content {
3679 ClientRequestContentV0::RepoPinStatusReq(r) => r.get_actor(self.id()),
3680 ClientRequestContentV0::PinRepo(r) => r.get_actor(self.id()),
3681 ClientRequestContentV0::TopicSub(r) => r.get_actor(self.id()),
3682 ClientRequestContentV0::PublishEvent(r) => r.get_actor(self.id()),
3683 ClientRequestContentV0::CommitGet(r) => r.get_actor(self.id()),
3684 ClientRequestContentV0::TopicSyncReq(r) => r.get_actor(self.id()),
3685 ClientRequestContentV0::BlocksPut(r) => r.get_actor(self.id()),
3686 ClientRequestContentV0::BlocksExist(r) => r.get_actor(self.id()),
3687 ClientRequestContentV0::BlocksGet(r) => r.get_actor(self.id()),
3688 ClientRequestContentV0::WalletPutExport(r) => r.get_actor(self.id()),
3689 _ => unimplemented!(),
3690 },
3691 }
3692 }
3693}
3694
3695impl TryFrom<ProtocolMessage> for ClientRequestContentV0 {
3696 type Error = ProtocolError;
3697 fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
3698 if let ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
3699 overlay,
3700 content:
3701 ClientMessageContentV0::ClientRequest(ClientRequest::V0(ClientRequestV0 {
3702 mut content,
3703 ..
3704 })),
3705 ..
3706 })) = msg
3707 {
3708 content.set_overlay(overlay);
3709 Ok(content)
3710 } else {
3711 log_debug!("INVALID {:?}", msg);
3712 Err(ProtocolError::InvalidValue)
3713 }
3714 }
3715}
3716
3717#[derive(Clone, Debug, Serialize, Deserialize)]
3719pub struct BlocksFoundV0 {
3720 pub found: Vec<BlockId>,
3722
3723 pub missing: Vec<BlockId>,
3725}
3726
3727#[derive(Clone, Debug, Serialize, Deserialize)]
3729pub enum BlocksFound {
3730 V0(BlocksFoundV0),
3731}
3732
3733impl BlocksFound {
3734 pub fn found(&self) -> &Vec<BlockId> {
3735 match self {
3736 BlocksFound::V0(o) => &o.found,
3737 }
3738 }
3739 pub fn missing(&self) -> &Vec<BlockId> {
3740 match self {
3741 BlocksFound::V0(o) => &o.missing,
3742 }
3743 }
3744}
3745
3746#[derive(Clone, Debug, Serialize, Deserialize)]
3748pub struct TopicSubResV0 {
3749 pub topic: TopicId,
3751 pub known_heads: Vec<ObjectId>,
3752 pub publisher: bool,
3753 pub commits_nbr: u64,
3754}
3755
3756#[derive(Clone, Debug, Serialize, Deserialize)]
3760pub enum TopicSubRes {
3761 V0(TopicSubResV0),
3762}
3763
3764impl TopicSubRes {
3765 pub fn topic_id(&self) -> &TopicId {
3766 match self {
3767 Self::V0(v0) => &v0.topic,
3768 }
3769 }
3770 pub fn is_publisher(&self) -> bool {
3771 match self {
3772 Self::V0(v0) => v0.publisher,
3773 }
3774 }
3775 pub fn new_from_heads(
3776 topics: HashSet<ObjectId>,
3777 publisher: bool,
3778 topic: TopicId,
3779 commits_nbr: u64,
3780 ) -> Self {
3781 TopicSubRes::V0(TopicSubResV0 {
3782 topic,
3783 known_heads: topics.into_iter().collect(),
3784 publisher,
3785 commits_nbr,
3786 })
3787 }
3788 pub fn known_heads(&self) -> &Vec<ObjectId> {
3789 match self {
3790 Self::V0(v0) => &v0.known_heads,
3791 }
3792 }
3793 pub fn commits_nbr(&self) -> u64 {
3794 match self {
3795 Self::V0(v0) => v0.commits_nbr,
3796 }
3797 }
3798}
3799
3800impl From<TopicId> for TopicSubRes {
3801 fn from(topic: TopicId) -> Self {
3802 TopicSubRes::V0(TopicSubResV0 {
3803 topic,
3804 known_heads: vec![],
3805 publisher: false,
3806 commits_nbr: 0,
3807 })
3808 }
3809}
3810
3811impl From<PublisherAdvert> for TopicSubRes {
3812 fn from(topic: PublisherAdvert) -> Self {
3813 TopicSubRes::V0(TopicSubResV0 {
3814 topic: topic.topic_id().clone(),
3815 known_heads: vec![],
3816 publisher: true,
3817 commits_nbr: 0,
3818 })
3819 }
3820}
3821
3822pub type RepoOpened = Vec<TopicSubRes>;
3823
3824#[derive(Clone, Debug, Serialize, Deserialize)]
3826pub enum ClientResponseContentV0 {
3827 EmptyResponse,
3828 Block(Block),
3829 RepoOpened(RepoOpened),
3830 TopicSubRes(TopicSubRes),
3831 TopicSyncRes(TopicSyncRes),
3832 BlocksFound(BlocksFound),
3833 RepoPinStatus(RepoPinStatus),
3834}
3835
3836#[derive(Clone, Debug, Serialize, Deserialize)]
3838pub struct ClientResponseV0 {
3839 pub id: i64,
3841
3842 pub result: u16,
3844
3845 pub content: ClientResponseContentV0,
3847}
3848
3849impl ClientResponse {
3850 pub fn set_result(&mut self, res: u16) {
3851 match self {
3852 Self::V0(v0) => v0.result = res,
3853 }
3854 }
3855}
3856
3857#[derive(Clone, Debug, Serialize, Deserialize)]
3859pub enum ClientResponse {
3860 V0(ClientResponseV0),
3861}
3862
3863impl From<ServerError> for ClientResponse {
3864 fn from(err: ServerError) -> ClientResponse {
3865 ClientResponse::V0(ClientResponseV0 {
3866 id: 0,
3867 result: err.into(),
3868 content: ClientResponseContentV0::EmptyResponse,
3869 })
3870 }
3871}
3872
3873#[derive(Debug)]
3874pub struct EmptyAppResponse(pub ());
3875
3876impl From<ServerError> for AppMessage {
3877 fn from(err: ServerError) -> AppMessage {
3878 AppMessage::V0(AppMessageV0 {
3879 id: 0,
3880 result: err.into(),
3881 content: AppMessageContentV0::EmptyResponse,
3882 })
3883 }
3884}
3885
3886impl<A> From<Result<A, ServerError>> for ProtocolMessage
3887where
3888 A: Into<ProtocolMessage> + std::fmt::Debug,
3889{
3890 fn from(res: Result<A, ServerError>) -> ProtocolMessage {
3891 match res {
3892 Ok(a) => a.into(),
3893 Err(e) => ProtocolMessage::from_client_response_err(e),
3894 }
3895 }
3896}
3897
3898impl From<()> for ProtocolMessage {
3899 fn from(_msg: ()) -> ProtocolMessage {
3900 let cm: ClientResponse = ServerError::Ok.into();
3901 cm.into()
3902 }
3903}
3904
3905impl ClientResponse {
3906 pub fn id(&self) -> i64 {
3907 match self {
3908 ClientResponse::V0(o) => o.id,
3909 }
3910 }
3911 pub fn set_id(&mut self, id: i64) {
3912 match self {
3913 ClientResponse::V0(v0) => {
3914 v0.id = id;
3915 }
3916 }
3917 }
3918 pub fn result(&self) -> u16 {
3919 match self {
3920 ClientResponse::V0(o) => o.result,
3921 }
3922 }
3923 pub fn block(&self) -> Option<&Block> {
3924 match self {
3925 ClientResponse::V0(o) => match &o.content {
3926 ClientResponseContentV0::Block(b) => Some(b),
3927 _ => panic!("this not a block response"),
3928 },
3929 }
3930 }
3931}
3932
3933impl TryFrom<ProtocolMessage> for ClientResponseContentV0 {
3934 type Error = ProtocolError;
3935 fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
3936 if let ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
3937 content:
3938 ClientMessageContentV0::ClientResponse(ClientResponse::V0(ClientResponseV0 {
3939 content,
3940 result: res,
3941 ..
3942 })),
3943 ..
3944 })) = msg
3945 {
3946 let err = ServerError::try_from(res).unwrap();
3947 if !err.is_err() {
3948 Ok(content)
3949 } else {
3950 Err(ProtocolError::ServerError)
3951 }
3952 } else {
3953 log_debug!("INVALID {:?}", msg);
3954 Err(ProtocolError::InvalidValue)
3955 }
3956 }
3957}
3958
3959#[derive(Clone, Debug, Serialize, Deserialize)]
3961pub enum ClientMessageContentV0 {
3962 ClientRequest(ClientRequest),
3963 ClientResponse(ClientResponse),
3964 ForwardedEvent(Event),
3965 ForwardedBlock(Block),
3966}
3967impl ClientMessageContentV0 {
3968 pub fn is_block(&self) -> bool {
3969 match self {
3970 Self::ClientRequest(ClientRequest::V0(ClientRequestV0 {
3971 content: ClientRequestContentV0::BlocksPut(_),
3972 ..
3973 })) => true,
3974 Self::ClientResponse(ClientResponse::V0(ClientResponseV0 {
3975 content: ClientResponseContentV0::Block(_),
3976 ..
3977 })) => true,
3978 _ => false,
3979 }
3980 }
3981}
3982
3983#[derive(Clone, Debug, Serialize, Deserialize)]
3985pub struct ClientMessageV0 {
3986 pub overlay: OverlayId,
3987 pub content: ClientMessageContentV0,
3988 #[serde(with = "serde_bytes")]
3990 pub padding: Vec<u8>,
3991}
3992
3993pub trait IStreamable {
3994 fn result(&self) -> u16;
3995 fn set_result(&mut self, result: u16);
3996}
3997
3998#[derive(Clone, Debug, Serialize, Deserialize)]
4000pub enum ClientMessage {
4001 V0(ClientMessageV0),
4002}
4003
4004impl IStreamable for ClientMessage {
4005 fn result(&self) -> u16 {
4006 match self {
4007 ClientMessage::V0(o) => match &o.content {
4008 ClientMessageContentV0::ClientResponse(r) => r.result(),
4009 ClientMessageContentV0::ClientRequest(_)
4010 | ClientMessageContentV0::ForwardedEvent(_)
4011 | ClientMessageContentV0::ForwardedBlock(_) => {
4012 panic!("it is not a response");
4013 }
4014 },
4015 }
4016 }
4017 fn set_result(&mut self, result: u16) {
4018 match self {
4019 ClientMessage::V0(o) => match &mut o.content {
4020 ClientMessageContentV0::ClientResponse(r) => r.set_result(result),
4021 ClientMessageContentV0::ClientRequest(_)
4022 | ClientMessageContentV0::ForwardedEvent(_)
4023 | ClientMessageContentV0::ForwardedBlock(_) => {
4024 panic!("it is not a response");
4025 }
4026 },
4027 }
4028 }
4029}
4030
4031impl ClientMessage {
4032 pub fn content_v0(&self) -> &ClientMessageContentV0 {
4033 match self {
4034 ClientMessage::V0(o) => &o.content,
4035 }
4036 }
4037 pub fn overlay_request(&self) -> &ClientRequest {
4038 match self {
4039 ClientMessage::V0(o) => match &o.content {
4040 ClientMessageContentV0::ClientRequest(r) => &r,
4041 _ => panic!("not an overlay request"),
4042 },
4043 }
4044 }
4045
4046 pub fn forwarded_event(self) -> Option<(Event, OverlayId)> {
4047 let overlay = self.overlay_id();
4048 match self {
4049 ClientMessage::V0(o) => match o.content {
4050 ClientMessageContentV0::ForwardedEvent(e) => Some((e, overlay)),
4051 _ => None,
4052 },
4053 }
4054 }
4055 pub fn overlay_id(&self) -> OverlayId {
4056 match self {
4057 ClientMessage::V0(o) => o.overlay,
4058 }
4059 }
4060 pub fn is_request(&self) -> bool {
4061 match self {
4062 ClientMessage::V0(o) => {
4063 matches!(o.content, ClientMessageContentV0::ClientRequest { .. })
4064 }
4065 }
4066 }
4067 pub fn is_response(&self) -> bool {
4068 match self {
4069 ClientMessage::V0(o) => {
4070 matches!(o.content, ClientMessageContentV0::ClientResponse { .. })
4071 }
4072 }
4073 }
4074 pub fn id(&self) -> Option<i64> {
4075 match self {
4076 ClientMessage::V0(o) => match &o.content {
4077 ClientMessageContentV0::ClientResponse(r) => Some(r.id()),
4078 ClientMessageContentV0::ClientRequest(r) => Some(r.id()),
4079 ClientMessageContentV0::ForwardedEvent(_)
4080 | ClientMessageContentV0::ForwardedBlock(_) => None,
4081 },
4082 }
4083 }
4084 pub fn set_id(&mut self, id: i64) {
4085 match self {
4086 ClientMessage::V0(o) => match &mut o.content {
4087 ClientMessageContentV0::ClientResponse(ref mut r) => r.set_id(id),
4088 ClientMessageContentV0::ClientRequest(ref mut r) => r.set_id(id),
4089 ClientMessageContentV0::ForwardedEvent(_)
4090 | ClientMessageContentV0::ForwardedBlock(_) => {
4091 panic!("it is an event")
4092 }
4093 },
4094 }
4095 }
4096
4097 pub fn block<'a>(&self) -> Option<&Block> {
4098 match self {
4099 ClientMessage::V0(o) => match &o.content {
4100 ClientMessageContentV0::ClientResponse(r) => r.block(),
4101 ClientMessageContentV0::ClientRequest(_)
4102 | ClientMessageContentV0::ForwardedEvent(_)
4103 | ClientMessageContentV0::ForwardedBlock(_) => {
4104 panic!("it is not a response");
4105 }
4106 },
4107 }
4108 }
4109
4110 pub fn get_actor(&self) -> Box<dyn EActor> {
4111 match self {
4112 ClientMessage::V0(o) => match &o.content {
4113 ClientMessageContentV0::ClientRequest(req) => req.get_actor(),
4114 ClientMessageContentV0::ClientResponse(_)
4115 | ClientMessageContentV0::ForwardedEvent(_)
4116 | ClientMessageContentV0::ForwardedBlock(_) => {
4117 panic!("it is not a request");
4118 }
4119 },
4120 }
4121 }
4122}
4123
4124#[derive(Clone, Debug, Serialize, Deserialize)]
4133pub struct ExtObjectGetV0 {
4134 pub overlay: OverlayId,
4136
4137 pub ids: Vec<ObjectId>,
4139
4140 pub include_files: bool,
4142}
4143
4144#[derive(Clone, Debug, Serialize, Deserialize)]
4146pub enum ExtObjectGet {
4147 V0(ExtObjectGetV0),
4148}
4149
4150#[derive(Clone, Debug, Serialize, Deserialize)]
4151pub struct ExtWalletGetExportV0 {
4152 pub id: SymKey,
4153 pub is_rendezvous: bool,
4154}
4155
4156pub type ExtTopicSyncReq = TopicSyncReq;
4158
4159#[derive(Clone, Debug, Serialize, Deserialize)]
4161pub enum ExtRequestContentV0 {
4162 WalletGetExport(ExtWalletGetExportV0),
4163 ExtObjectGet(ExtObjectGetV0),
4164 ExtTopicSyncReq(ExtTopicSyncReq),
4165 }
4168
4169impl ExtRequestContentV0 {
4170 pub fn get_actor(&self) -> Box<dyn EActor> {
4171 match self {
4172 Self::WalletGetExport(a) => a.get_actor(),
4173 Self::ExtObjectGet(a) => a.get_actor(),
4174 _ => unimplemented!(), }
4176 }
4177}
4178
4179#[derive(Clone, Debug, Serialize, Deserialize)]
4181pub struct ExtRequestV0 {
4182 pub id: i64,
4184
4185 pub content: ExtRequestContentV0,
4187}
4188
4189#[derive(Clone, Debug, Serialize, Deserialize)]
4194pub enum ExtRequest {
4195 V0(ExtRequestV0),
4196}
4197
4198impl ExtRequest {
4199 pub fn id(&self) -> i64 {
4200 match self {
4201 ExtRequest::V0(v0) => v0.id,
4202 }
4203 }
4204 pub fn set_id(&mut self, id: i64) {
4205 match self {
4206 ExtRequest::V0(v0) => {
4207 v0.id = id;
4208 }
4209 }
4210 }
4211 pub fn get_actor(&self) -> Box<dyn EActor> {
4212 match self {
4213 Self::V0(a) => a.content.get_actor(),
4214 }
4215 }
4216}
4217
4218#[derive(Clone, Debug, Serialize, Deserialize)]
4219pub struct ExportedWallet(pub serde_bytes::ByteBuf);
4220
4221#[derive(Clone, Debug, Serialize, Deserialize)]
4223pub enum ExtResponseContentV0 {
4224 EmptyResponse,
4225 Block(Block),
4226 Blocks(Vec<Block>),
4227 Wallet(ExportedWallet),
4228 }
4231
4232impl TryFrom<ProtocolMessage> for ExtResponseContentV0 {
4233 type Error = ProtocolError;
4234 fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
4235 if let ProtocolMessage::ExtResponse(ExtResponse::V0(ExtResponseV0 {
4236 content,
4237 result,
4238 ..
4239 })) = msg
4240 {
4241 let err = ServerError::try_from(result).unwrap();
4242 if !err.is_err() {
4243 Ok(content)
4244 } else {
4245 Err(ProtocolError::ServerError)
4246 }
4247 } else {
4248 log_debug!("INVALID {:?}", msg);
4249 Err(ProtocolError::InvalidValue)
4250 }
4251 }
4252}
4253
4254#[derive(Clone, Debug, Serialize, Deserialize)]
4256pub struct ExtResponseV0 {
4257 pub id: i64,
4259
4260 pub result: u16,
4262
4263 pub content: ExtResponseContentV0,
4265}
4266
4267#[derive(Clone, Debug, Serialize, Deserialize)]
4269pub enum ExtResponse {
4270 V0(ExtResponseV0),
4271}
4272
4273impl ExtResponse {
4274 pub fn id(&self) -> i64 {
4275 match self {
4276 ExtResponse::V0(v0) => v0.id,
4277 }
4278 }
4279 pub fn set_id(&mut self, id: i64) {
4280 match self {
4281 ExtResponse::V0(v0) => {
4282 v0.id = id;
4283 }
4284 }
4285 }
4286 pub fn result(&self) -> u16 {
4287 match self {
4288 Self::V0(o) => o.result,
4289 }
4290 }
4291 pub fn content_v0(&self) -> ExtResponseContentV0 {
4292 match self {
4293 Self::V0(o) => o.content.clone(),
4294 }
4295 }
4296}
4297
4298impl TryFrom<ProtocolMessage> for ExtResponse {
4299 type Error = ProtocolError;
4300 fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
4301 if let ProtocolMessage::ExtResponse(ext_res) = msg {
4302 Ok(ext_res)
4303 } else {
4304 Err(ProtocolError::InvalidValue)
4305 }
4306 }
4307}
4308
4309impl From<Result<ExtResponseContentV0, ServerError>> for ExtResponseV0 {
4310 fn from(res: Result<ExtResponseContentV0, ServerError>) -> ExtResponseV0 {
4311 match res {
4312 Err(e) => ExtResponseV0 {
4313 id: 0,
4314 result: e.into(),
4315 content: ExtResponseContentV0::EmptyResponse,
4316 },
4317 Ok(content) => ExtResponseV0 {
4318 id: 0,
4319 result: 0,
4320 content,
4321 },
4322 }
4323 }
4324}
4325
4326impl From<ExtResponseV0> for ProtocolMessage {
4327 fn from(msg: ExtResponseV0) -> ProtocolMessage {
4328 ProtocolMessage::ExtResponse(ExtResponse::V0(msg))
4329 }
4330}
4331
4332#[doc(hidden)]
4336pub static MAGIC_NG_REQUEST: [u8; 2] = [78u8, 71u8];
4337#[doc(hidden)]
4338pub static MAGIC_NG_RESPONSE: [u8; 4] = [89u8, 88u8, 78u8, 75u8];
4339
4340#[derive(Clone, Debug)]
4341pub enum Authorization {
4342 Discover,
4343 ExtMessage,
4344 Core,
4345 Client((PubKey, Option<Option<[u8; 32]>>)),
4346 OverlayJoin(PubKey),
4347 Admin(PubKey),
4348}
4349
4350#[derive(Clone, Debug, Serialize, Deserialize)]
4352pub struct ProbeResponse {
4353 #[serde(with = "serde_bytes")]
4355 pub magic: Vec<u8>,
4356
4357 pub peer_id: Option<PubKey>,
4360}
4361
4362#[derive(Clone, Debug, Serialize, Deserialize)]
4364pub struct RelayRequest {
4365 pub address: BindAddress,
4367}
4368
4369#[derive(Clone, Debug, Serialize, Deserialize)]
4371pub struct RelayResponse {
4372 #[serde(with = "serde_bytes")]
4374 pub magic: Vec<u8>,
4375
4376 pub result: u16,
4378}
4379
4380#[derive(Clone, Debug, Serialize, Deserialize)]
4382pub struct TunnelRequest {
4383 #[serde(with = "serde_bytes")]
4385 pub magic: Vec<u8>,
4386
4387 pub remote_addr: BindAddress,
4389}
4390
4391#[derive(Clone, Debug, Serialize, Deserialize)]
4393pub struct TunnelResponse {
4394 #[serde(with = "serde_bytes")]
4396 pub magic: Vec<u8>,
4397
4398 pub result: u16,
4400}
4401
4402#[derive(Clone, Debug, Serialize, Deserialize)]
4403pub enum ProtocolMessage {
4404 Probe([u8; 2]),
4405 ProbeResponse(ProbeResponse),
4406 Relay(RelayRequest),
4407 RelayResponse(RelayResponse),
4408 Tunnel(TunnelRequest),
4409 TunnelResponse(TunnelResponse),
4410 Noise(Noise),
4411 Start(StartProtocol),
4412 ServerHello(ServerHello),
4413 ClientAuth(ClientAuth),
4414 AuthResult(AuthResult),
4415 ExtRequest(ExtRequest),
4416 ExtResponse(ExtResponse),
4417 AdminResponse(AdminResponse),
4419 ClientMessage(ClientMessage),
4420 AppMessage(AppMessage),
4421 CoreMessage(CoreMessage),
4422}
4423
4424impl TryFrom<&ProtocolMessage> for ServerError {
4425 type Error = NgError;
4426 fn try_from(msg: &ProtocolMessage) -> Result<Self, NgError> {
4427 if let ProtocolMessage::ClientMessage(ref bm) = msg {
4428 let res = bm.result();
4429 if res != 0 {
4430 return Ok(ServerError::try_from(res).unwrap());
4431 }
4432 }
4433 if let ProtocolMessage::ExtResponse(ref bm) = msg {
4434 let res = bm.result();
4435 if res != 0 {
4436 return Ok(ServerError::try_from(res).unwrap());
4437 }
4438 }
4439 if let ProtocolMessage::AppMessage(ref bm) = msg {
4440 let res = bm.result();
4441 if res != 0 {
4442 return Ok(ServerError::try_from(res).unwrap());
4443 }
4444 }
4445 Err(NgError::NotAServerError)
4446 }
4447}
4448
4449impl ProtocolMessage {
4450 pub fn id(&self) -> Option<i64> {
4451 match self {
4452 ProtocolMessage::ExtRequest(ext_req) => Some(ext_req.id()),
4453 ProtocolMessage::ExtResponse(ext_res) => Some(ext_res.id()),
4454 ProtocolMessage::ClientMessage(client_msg) => client_msg.id(),
4455 ProtocolMessage::AppMessage(app_msg) => app_msg.id(),
4456 _ => None,
4457 }
4458 }
4459 pub fn set_id(&mut self, id: i64) {
4460 match self {
4461 ProtocolMessage::ExtRequest(ext_req) => ext_req.set_id(id),
4462 ProtocolMessage::ExtResponse(ext_res) => ext_res.set_id(id),
4463 ProtocolMessage::ClientMessage(client_msg) => client_msg.set_id(id),
4464 ProtocolMessage::AppMessage(app_msg) => app_msg.set_id(id),
4465 _ => panic!("cannot set ID"),
4466 }
4467 }
4468 pub fn type_id(&self) -> TypeId {
4469 match self {
4470 ProtocolMessage::Noise(a) => a.type_id(),
4471 ProtocolMessage::Start(a) => a.type_id(),
4472 ProtocolMessage::ServerHello(a) => a.type_id(),
4473 ProtocolMessage::ClientAuth(a) => a.type_id(),
4474 ProtocolMessage::AuthResult(a) => a.type_id(),
4475 ProtocolMessage::ExtRequest(a) => a.type_id(),
4476 ProtocolMessage::ExtResponse(a) => a.type_id(),
4477 ProtocolMessage::ClientMessage(a) => a.type_id(),
4478 ProtocolMessage::CoreMessage(a) => a.type_id(),
4479 ProtocolMessage::AppMessage(a) => a.type_id(),
4480 ProtocolMessage::AdminResponse(a) => a.type_id(),
4482 ProtocolMessage::Probe(a) => a.type_id(),
4483 ProtocolMessage::ProbeResponse(a) => a.type_id(),
4484 ProtocolMessage::Relay(a) => a.type_id(),
4485 ProtocolMessage::RelayResponse(a) => a.type_id(),
4486 ProtocolMessage::Tunnel(a) => a.type_id(),
4487 ProtocolMessage::TunnelResponse(a) => a.type_id(),
4488 }
4489 }
4490
4491 pub(crate) fn is_streamable(&self) -> Option<&dyn IStreamable> {
4492 match self {
4493 ProtocolMessage::ClientMessage(s) => Some(s as &dyn IStreamable),
4494 ProtocolMessage::AppMessage(s) => Some(s as &dyn IStreamable),
4495 _ => None,
4496 }
4497 }
4498
4499 pub fn get_actor(&self) -> Box<dyn EActor> {
4500 match self {
4501 ProtocolMessage::Start(a) => a.get_actor(),
4503 ProtocolMessage::ClientMessage(a) => a.get_actor(),
4504 ProtocolMessage::AppMessage(a) => a.get_actor(),
4505 _ => unimplemented!(),
4512 }
4513 }
4514
4515 pub fn from_client_response_err(err: ServerError) -> ProtocolMessage {
4516 let res: ClientResponse = err.into();
4517 res.into()
4518 }
4519
4520 pub fn from_client_request_v0(
4521 req: ClientRequestContentV0,
4522 overlay: OverlayId,
4523 ) -> ProtocolMessage {
4524 ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
4525 overlay,
4526 content: ClientMessageContentV0::ClientRequest(ClientRequest::V0(ClientRequestV0 {
4527 id: 0,
4528 content: req,
4529 })),
4530 padding: vec![],
4531 }))
4532 }
4533
4534 pub fn is_block(&self) -> bool {
4535 match self {
4536 ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
4537 content: c,
4538 ..
4539 })) => c.is_block(),
4540 _ => false,
4541 }
4542 }
4543}
4544
4545impl From<ClientResponseContentV0> for ClientResponse {
4546 fn from(msg: ClientResponseContentV0) -> ClientResponse {
4547 ClientResponse::V0(ClientResponseV0 {
4548 id: 0,
4549 result: 0,
4550 content: msg,
4551 })
4552 }
4553}
4554
4555impl From<ClientResponseContentV0> for ProtocolMessage {
4556 fn from(msg: ClientResponseContentV0) -> ProtocolMessage {
4557 let client_res = ClientResponse::V0(ClientResponseV0 {
4558 id: 0,
4559 result: 0,
4560 content: msg,
4561 });
4562 client_res.into()
4563 }
4564}
4565
4566impl From<ClientResponse> for ProtocolMessage {
4567 fn from(msg: ClientResponse) -> ProtocolMessage {
4568 ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
4569 overlay: OverlayId::nil(),
4570 content: ClientMessageContentV0::ClientResponse(msg),
4571 padding: vec![],
4572 }))
4573 }
4574}
4575
4576#[derive(Clone, Debug, Serialize, Deserialize)]
4582pub struct ClientAuthContentV0 {
4583 pub user: PubKey,
4585
4586 pub client: PubKey,
4588
4589 pub info: ClientInfoV0,
4590
4591 pub registration: Option<Option<[u8; 32]>>,
4592
4593 #[serde(with = "serde_bytes")]
4595 pub nonce: Vec<u8>,
4596}
4597
4598#[derive(Clone, Debug, Serialize, Deserialize)]
4600pub struct ClientAuthV0 {
4601 pub content: ClientAuthContentV0,
4603
4604 pub sig: Sig,
4606
4607 pub client_sig: Sig,
4609}
4610
4611#[derive(Clone, Debug, Serialize, Deserialize)]
4613pub enum ClientAuth {
4614 V0(ClientAuthV0),
4615}
4616
4617impl ClientAuth {
4618 pub fn content_v0(&self) -> ClientAuthContentV0 {
4619 match self {
4620 ClientAuth::V0(o) => o.content.clone(),
4621 }
4622 }
4623 pub fn sig(&self) -> Sig {
4624 match self {
4625 ClientAuth::V0(o) => o.sig,
4626 }
4627 }
4628 pub fn user(&self) -> PubKey {
4629 match self {
4630 ClientAuth::V0(o) => o.content.user,
4631 }
4632 }
4633 pub fn client(&self) -> PubKey {
4634 match self {
4635 ClientAuth::V0(o) => o.content.client,
4636 }
4637 }
4638 pub fn nonce(&self) -> &Vec<u8> {
4639 match self {
4640 ClientAuth::V0(o) => &o.content.nonce,
4641 }
4642 }
4643 pub fn registration(&self) -> Option<Option<[u8; 32]>> {
4644 match self {
4645 ClientAuth::V0(o) => o.content.registration,
4646 }
4647 }
4648}
4649
4650impl From<ClientAuth> for ProtocolMessage {
4651 fn from(msg: ClientAuth) -> ProtocolMessage {
4652 ProtocolMessage::ClientAuth(msg)
4653 }
4654}
4655
4656#[derive(Clone, Debug, Serialize, Deserialize)]
4658pub struct AuthResultV0 {
4659 pub result: u16,
4660 #[serde(with = "serde_bytes")]
4661 pub metadata: Vec<u8>,
4662}
4663
4664#[derive(Clone, Debug, Serialize, Deserialize)]
4666pub enum AuthResult {
4667 V0(AuthResultV0),
4668}
4669
4670impl AuthResult {
4671 pub fn result(&self) -> u16 {
4672 match self {
4673 AuthResult::V0(o) => o.result,
4674 }
4675 }
4676 pub fn metadata(&self) -> &Vec<u8> {
4677 match self {
4678 AuthResult::V0(o) => &o.metadata,
4679 }
4680 }
4681}
4682
4683impl From<AuthResult> for ProtocolMessage {
4684 fn from(msg: AuthResult) -> ProtocolMessage {
4685 ProtocolMessage::AuthResult(msg)
4686 }
4687}
4688
4689#[derive(Clone, Debug, Serialize, Deserialize)]
4703pub struct RepoLinkV0 {
4704 pub id: RepoId,
4706
4707 pub read_cap: ReadCap,
4710
4711 pub overlay: OverlayLink,
4716
4717 pub peers: Vec<PeerAdvert>,
4719}
4720
4721#[derive(Clone, Debug, Serialize, Deserialize)]
4723pub enum RepoLink {
4724 V0(RepoLinkV0),
4725}
4726
4727impl RepoLink {
4728 pub fn id(&self) -> &RepoId {
4729 match self {
4730 RepoLink::V0(o) => &o.id,
4731 }
4732 }
4733 pub fn peers(&self) -> &Vec<PeerAdvert> {
4734 match self {
4735 RepoLink::V0(o) => &o.peers,
4736 }
4737 }
4738}
4739
4740#[derive(Clone, Debug, Serialize, Deserialize)]
4746pub struct PublicRepoLinkV0 {
4747 pub repo: RepoId,
4749
4750 pub branch: Option<BranchId>,
4753
4754 pub heads: Vec<ObjectRef>,
4757
4758 pub snapshot: Option<ObjectRef>,
4760
4761 pub public_store: PubKey,
4763
4764 pub peers: Vec<PeerAdvert>,
4766}
4767
4768#[derive(Clone, Debug, Serialize, Deserialize)]
4770pub enum PublicRepoLink {
4771 V0(PublicRepoLinkV0),
4772}
4773
4774#[derive(Clone, Debug, Serialize, Deserialize)]
4783pub struct ReadBranchLinkV0 {
4784 pub repo: RepoId,
4786
4787 pub branch: BranchId, pub topic: TopicId,
4790
4791 pub heads: Vec<ObjectRef>,
4794
4795 pub read_cap: ReadCap,
4798
4799 pub overlay: OverlayLink,
4801
4802 pub peers: Vec<PeerAdvert>,
4804}
4805
4806#[derive(Clone, Debug, Serialize, Deserialize)]
4808pub enum ReadBranchLink {
4809 V0(ReadBranchLinkV0),
4810}
4811
4812#[derive(Clone, Debug, Serialize, Deserialize)]
4817pub struct ObjectLinkV0 {
4818 pub repo: Option<RepoId>,
4822
4823 pub topic: Option<TopicId>,
4829
4830 pub objects: Vec<ObjectRef>,
4831
4832 pub overlay: OverlayLink,
4834
4835 pub peers: Vec<PeerAdvert>,
4837}
4838
4839#[derive(Clone, Debug, Serialize, Deserialize)]
4841pub enum ObjectLink {
4842 V0(ObjectLinkV0),
4843}
4844
4845#[derive(Clone, Debug, Serialize, Deserialize)]
4847pub enum NgLinkV0 {
4848 Repo(RepoLink),
4849 PublicRepo(PublicRepoLink),
4850 Branch(ReadBranchLink),
4851 Object(ObjectLink),
4852}
4853
4854#[derive(Clone, Debug, Serialize, Deserialize)]
4856pub enum NgLink {
4857 V0(NgLinkV0),
4858}
4859
4860#[cfg(test)]
4863mod test {
4864
4865 use crate::types::{BootstrapContentV0, BrokerServerTypeV0, BrokerServerV0, Invitation};
4866 use ng_repo::types::PubKey;
4867
4868 #[test]
4869 pub fn invitation() {
4870 let inv = Invitation::new_v0(
4871 BootstrapContentV0 {
4872 servers: vec![BrokerServerV0 {
4873 server_type: BrokerServerTypeV0::Localhost(14400),
4874 can_verify: false,
4875 can_forward: false,
4876 peer_id: PubKey::Ed25519PubKey([
4877 95, 73, 225, 250, 3, 147, 24, 164, 177, 211, 34, 244, 45, 130, 111, 136,
4878 229, 145, 53, 167, 50, 168, 140, 227, 65, 111, 203, 41, 210, 186, 162, 149,
4879 ]),
4880 }],
4881 },
4882 Some("test invitation".to_string()),
4883 None,
4884 );
4885
4886 println!("{:?}", inv.get_urls());
4887 }
4888}