nym_ip_packet_requests/v8/
response.rs1use nym_bin_common::build_information::BinaryBuildInformationOwned;
2use serde::{Deserialize, Serialize};
3
4use crate::{IpPair, make_bincode_serializer};
5
6use super::VERSION;
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
9pub struct IpPacketResponse {
10 pub version: u8,
11 pub data: IpPacketResponseData,
12}
13
14#[derive(Clone, Debug, Serialize, Deserialize)]
15pub enum IpPacketResponseData {
16 Data(DataResponse),
17 Control(Box<ControlResponse>),
18}
19
20#[derive(Clone, Debug, Serialize, Deserialize)]
21pub struct DataResponse {
22 pub ip_packet: bytes::Bytes,
23}
24
25#[derive(Clone, Debug, Serialize, Deserialize)]
26pub enum ControlResponse {
27 Connect(ConnectResponse),
29
30 Disconnect(DisconnectResponse),
32
33 UnrequestedDisconnect(UnrequestedDisconnect),
35
36 Pong(PongResponse),
38
39 Health(Box<HealthResponse>),
41
42 Info(InfoResponse),
44}
45
46#[derive(Clone, Debug, Serialize, Deserialize)]
47pub struct ConnectResponse {
48 pub request_id: u64,
49 pub reply: ConnectResponseReply,
50}
51
52#[derive(Clone, Debug, Serialize, Deserialize)]
53pub enum ConnectResponseReply {
54 Success(ConnectSuccess),
55 Failure(ConnectFailureReason),
56}
57
58#[derive(Clone, Debug, Serialize, Deserialize)]
59pub struct ConnectSuccess {
60 pub ips: IpPair,
61}
62
63#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
64pub enum ConnectFailureReason {
65 #[error("client is already connected")]
66 ClientAlreadyConnected,
67
68 #[error("no available ip address")]
69 NoAvailableIp,
70
71 #[error("{0}")]
72 Other(String),
73}
74
75#[derive(Clone, Debug, Serialize, Deserialize)]
76pub struct DisconnectResponse {
77 pub request_id: u64,
78 pub reply: DisconnectResponseReply,
79}
80
81#[derive(Clone, Debug, Serialize, Deserialize)]
82pub enum DisconnectResponseReply {
83 Success,
84 Failure(DisconnectFailureReason),
85}
86
87#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
88pub enum DisconnectFailureReason {
89 #[error("client is not connected")]
90 ClientNotConnected,
91
92 #[error("{0}")]
93 Other(String),
94}
95
96#[derive(Clone, Debug, Serialize, Deserialize)]
97pub struct UnrequestedDisconnect {
98 pub reason: UnrequestedDisconnectReason,
99}
100
101#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
102pub enum UnrequestedDisconnectReason {
103 #[error("client mixnet traffic timeout")]
104 ClientMixnetTrafficTimeout,
105
106 #[error("client tun traffic timeout")]
107 ClientTunTrafficTimeout,
108
109 #[error("{0}")]
110 Other(String),
111}
112
113#[derive(Clone, Debug, Serialize, Deserialize)]
114pub struct PongResponse {
115 pub request_id: u64,
116}
117
118#[derive(Clone, Debug, Serialize, Deserialize)]
119pub struct HealthResponse {
120 pub request_id: u64,
121 pub reply: HealthResponseReply,
122}
123
124#[derive(Clone, Debug, Serialize, Deserialize)]
125pub struct HealthResponseReply {
126 pub build_info: BinaryBuildInformationOwned,
128
129 pub routable: Option<bool>,
131}
132
133#[derive(Clone, Debug, Serialize, Deserialize)]
134pub struct InfoResponse {
135 pub request_id: u64,
136 pub reply: InfoResponseReply,
137 pub level: InfoLevel,
138}
139
140#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
141pub enum InfoResponseReply {
142 #[error("{msg}")]
143 Generic { msg: String },
144
145 #[error("version mismatch: response is v{request_version} and response is v{response_version}")]
146 VersionMismatch {
147 request_version: u8,
148 response_version: u8,
149 },
150
151 #[error("destination failed exit policy filter check: {dst}")]
152 ExitPolicyFilterCheckFailed { dst: String },
153}
154
155#[derive(Clone, Debug, Serialize, Deserialize)]
156pub enum InfoLevel {
157 Info,
158 Warn,
159 Error,
160}
161
162impl IpPacketResponse {
163 pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
164 Self {
165 version: VERSION,
166 data: IpPacketResponseData::Data(DataResponse { ip_packet }),
167 }
168 }
169
170 pub fn id(&self) -> Option<u64> {
171 match &self.data {
172 IpPacketResponseData::Data(_) => None,
173 IpPacketResponseData::Control(response) => response.id(),
174 }
175 }
176
177 pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
178 use bincode::Options;
179 make_bincode_serializer().serialize(self)
180 }
181
182 pub fn from_bytes(data: &[u8]) -> Result<Self, bincode::Error> {
183 use bincode::Options;
184 make_bincode_serializer().deserialize(data)
185 }
186
187 pub fn from_reconstructed_message(
188 message: &nym_sphinx::receiver::ReconstructedMessage,
189 ) -> Result<Self, bincode::Error> {
190 Self::from_bytes(&message.message)
191 }
192}
193
194impl IpPacketResponseData {
195 pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
196 use bincode::Options;
197 make_bincode_serializer().serialize(self)
198 }
199}
200
201impl ControlResponse {
202 fn id(&self) -> Option<u64> {
203 match self {
204 ControlResponse::Connect(response) => Some(response.request_id),
205 ControlResponse::Disconnect(response) => Some(response.request_id),
206 ControlResponse::UnrequestedDisconnect(_) => None,
207 ControlResponse::Pong(response) => Some(response.request_id),
208 ControlResponse::Health(response) => Some(response.request_id),
209 ControlResponse::Info(response) => Some(response.request_id),
210 }
211 }
212}
213
214impl ConnectResponseReply {
215 pub fn is_success(&self) -> bool {
216 match self {
217 ConnectResponseReply::Success(_) => true,
218 ConnectResponseReply::Failure(_) => false,
219 }
220 }
221}