Line data Source code
1 : /*
2 : * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 : #pragma once
18 :
19 : #include <string>
20 : #include <string_view>
21 : #include <msgpack.hpp>
22 :
23 : #include <opendht/crypto.h>
24 : #include <opendht/infohash.h>
25 :
26 : using namespace std::literals;
27 : using NodeId = dht::h256;
28 :
29 : namespace jami {
30 :
31 : namespace swarm_protocol {
32 :
33 : static constexpr int version = 3;
34 : static constexpr size_t MAX_MOBILE_CERTIFICATE_SIZE = 64 * 1024;
35 : static constexpr size_t MAX_MOBILE_CERTIFICATES_SIZE = 256 * 1024;
36 : static constexpr size_t MAX_MOBILE_LEASE_SIGNATURE_SIZE = 1024;
37 : static constexpr size_t MAX_MOBILE_LEASE_IDENTIFIER_SIZE = 128;
38 : static constexpr size_t MAX_MOBILE_NODE_INFOS = 128;
39 : static constexpr std::chrono::days MAX_MOBILE_LEASE_DURATION {30};
40 : static constexpr std::chrono::days MOBILE_LEASE_RENEWAL_THRESHOLD {14};
41 : // 2026-10-01T00:00:00Z. A fixed cutoff cannot be extended by restart or gossip.
42 : static constexpr int64_t LEGACY_MOBILE_NODE_SUNSET {1'790'812'800};
43 :
44 : // Certificates are not gossiped: leases travel alone and the certificate needed
45 : // to verify one is resolved from the local store, from the peer that gossiped
46 : // the lease, or from the DHT. A lease that cannot be resolved is simply dropped;
47 : // the next gossip round re-announces it. These bound that resolution.
48 : static constexpr size_t MAX_CERT_REQUEST_IDS = 16;
49 : static constexpr size_t MAX_PENDING_MOBILE_LEASES = 64;
50 : static constexpr std::chrono::seconds CERT_REQUEST_TIMEOUT {10};
51 :
52 : enum class Query : uint8_t { FIND = 1, FOUND = 2, CERT_REQ = 3, CERT_RES = 4 };
53 :
54 : using NodeId = dht::PkId;
55 :
56 : struct Request
57 : {
58 : Query q; // Type of query
59 : int num; // Number of nodes
60 : NodeId nodeId;
61 3088 : MSGPACK_DEFINE_MAP(q, num, nodeId);
62 : };
63 :
64 : struct MobileLease
65 : {
66 : uint8_t format_version {1};
67 : std::string conversation_id;
68 : dht::InfoHash issuer_id;
69 : NodeId device_id;
70 : int64_t issued_at {0};
71 : int64_t expires_at {0};
72 : dht::Blob signature;
73 :
74 19 : MSGPACK_DEFINE_MAP(format_version, conversation_id, issuer_id, device_id, issued_at, expires_at, signature);
75 : };
76 :
77 : struct MobileNodeInfo
78 : {
79 : NodeId id;
80 : std::optional<MobileLease> lease;
81 :
82 28 : MSGPACK_DEFINE_MAP(id, lease);
83 : };
84 :
85 : dht::Blob mobileLeasePayload(const MobileLease& lease);
86 :
87 : struct Response
88 : {
89 : Query q;
90 : std::vector<NodeId> nodes;
91 : std::vector<NodeId> mobile_nodes;
92 : std::vector<MobileNodeInfo> mobile_node_infos;
93 :
94 3020 : MSGPACK_DEFINE_MAP(q, nodes, mobile_nodes, mobile_node_infos);
95 : };
96 :
97 : /**
98 : * Ask a peer for the device certificates needed to verify mobile leases it
99 : * gossiped to us. Only ids the peer itself announced as mobile are answered.
100 : */
101 : struct CertRequest
102 : {
103 : std::vector<NodeId> ids;
104 :
105 14 : MSGPACK_DEFINE_MAP(ids);
106 : };
107 :
108 : struct CertResponse
109 : {
110 : std::vector<dht::Blob> certificates;
111 :
112 12 : MSGPACK_DEFINE_MAP(certificates);
113 : };
114 :
115 : struct Message
116 : {
117 : int v = version;
118 : bool is_mobile {false};
119 : std::optional<MobileNodeInfo> self_mobile_info;
120 : std::optional<Request> request;
121 : std::optional<Response> response;
122 : std::optional<CertRequest> cert_request;
123 : std::optional<CertResponse> cert_response;
124 6151 : MSGPACK_DEFINE_MAP(v, is_mobile, self_mobile_info, request, response, cert_request, cert_response);
125 : };
126 :
127 : }; // namespace swarm_protocol
128 :
129 : } // namespace jami
130 9110 : MSGPACK_ADD_ENUM(jami::swarm_protocol::Query);
|