1use crate::base::Base;
6use crate::error::Error;
7use crate::types::*;
8
9pub mod request;
10pub use request::{Request, RequestKind};
11
12pub mod response;
13pub use response::{Response, ResponseKind, Status};
14
15pub const BUFF_SIZE: usize = 10 * 1024;
16
17#[derive(Clone, PartialEq, Debug)]
19pub enum Message {
20 Request(Request),
21 Response(Response),
22}
23
24impl Message {
25 pub fn request(req: Request) -> Self {
26 Self::Request(req)
27 }
28
29 pub fn response(resp: Response) -> Self {
30 Self::Response(resp)
31 }
32
33 pub fn request_id(&self) -> RequestId {
34 match self {
35 Message::Request(req) => req.id,
36 Message::Response(resp) => resp.id,
37 }
38 }
39
40 pub fn from(&self) -> Id {
41 match self {
42 Message::Request(req) => req.from.clone(),
43 Message::Response(resp) => resp.from.clone(),
44 }
45 }
46
47 pub fn flags_mut(&mut self) -> &mut Flags {
48 match self {
49 Message::Request(req) => req.flags(),
50 Message::Response(resp) => resp.flags(),
51 }
52 }
53
54 pub fn pub_key(&self) -> Option<PublicKey> {
55 match self {
56 Message::Request(req) => req.public_key.clone(),
57 Message::Response(resp) => resp.public_key.clone(),
58 }
59 }
60
61 pub fn set_public_key(&mut self, pub_key: PublicKey) {
62 match self {
63 Message::Request(req) => req.common.public_key = Some(pub_key),
64 Message::Response(resp) => resp.common.public_key = Some(pub_key),
65 }
66 }
67}
68
69impl Into<Base> for Message {
70 fn into(self) -> Base {
71 match self {
72 Message::Request(req) => req.into(),
73 Message::Response(resp) => resp.into(),
74 }
75 }
76}
77
78impl Message {
79 pub fn parse<'a, V, T: AsRef<[u8]>>(data: T, pub_key_s: V) -> Result<(Message, usize), Error>
82 where
83 V: Fn(&Id) -> Option<PublicKey>,
84 {
85 let (b, n) = Base::parse(data, &pub_key_s, |_id| None)?;
86
87 let m = Message::convert(b, &pub_key_s)?;
88
89 Ok((m, n))
90 }
91}
92
93impl Message {
94 pub fn convert<V>(base: Base, key_source: V) -> Result<Message, Error>
95 where
96 V: Fn(&Id) -> Option<PublicKey>,
97 {
98 let header = base.header();
99 let app_id = header.application_id();
100 let kind = header.kind();
101
102 if app_id != 0 {
104 error!(
105 "Error converting application-specific base object {:?} to message",
106 kind
107 );
108 return Err(Error::InvalidMessageType);
109 }
110
111 if kind.is_request() {
113 Ok(Message::Request(Request::convert(base, key_source)?))
114 } else if kind.is_response() {
115 Ok(Message::Response(Response::convert(base, key_source)?))
116 } else {
117 error!("Error converting base object of kind {:?} to message", kind);
118 Err(Error::InvalidMessageType)
119 }
120 }
121}
122
123#[derive(Clone, Debug)]
124pub struct Common {
125 pub from: Id,
126 pub id: RequestId,
127 pub flags: Flags,
128
129 pub remote_address: Option<Address>,
130 pub public_key: Option<PublicKey>,
131}
132
133#[cfg(test)]
134mod tests {
135
136 use std::net::{IpAddr, Ipv4Addr, SocketAddr};
137
138 use super::*;
139 use crate::base::{Body, Header};
140 use crate::page::{Page, PageInfo, PageOptions};
141 use crate::types::PageKind;
142
143 use crate::crypto;
144 #[test]
145 fn encode_decode_messages() {
146 let mut buff = vec![0u8; BUFF_SIZE];
147
148 let (pub_key, pri_key) =
149 crypto::new_pk().expect("Error generating new public/private key pair");
150 let id = crypto::hash(&pub_key).expect("Error generating new ID");
151 let fake_id = crypto::hash(&[0, 1, 2, 3, 4]).expect("Error generating fake target ID");
152 let flags = Flags::ADDRESS_REQUEST;
153 let request_id = 120;
154
155 let header = Header {
157 kind: PageKind::Generic.into(),
158 ..Default::default()
159 };
160 let mut page = Page::new(
161 id.clone(),
162 header,
163 PageInfo::primary(pub_key.clone()),
164 Body::None,
165 PageOptions::default(),
166 );
167
168 let mut b = Base::from(&page);
169 let n = b
170 .encode(Some(&pri_key), None, &mut buff)
171 .expect("Error signing page");
172 let sig = b.signature().clone().unwrap();
173
174 page.set_signature(sig);
175 page.raw = Some(buff[0..n].to_vec());
176
177 let messages: Vec<Message> = vec![
178 Message::Request(Request::new(
179 id.clone(),
180 0,
181 RequestKind::Hello,
182 flags.clone(),
183 )),
184 Message::Request(Request::new(
185 id.clone(),
186 1,
187 RequestKind::Ping,
188 flags.clone(),
189 )),
190 Message::Request(Request::new(
191 id.clone(),
192 request_id,
193 RequestKind::FindNode(fake_id.clone()),
194 flags.clone(),
195 )),
196 Message::Request(Request::new(
197 id.clone(),
198 request_id,
199 RequestKind::Store(id.clone(), vec![page.clone()]),
200 flags.clone(),
201 )),
202 Message::Request(Request::new(
203 id.clone(),
204 request_id,
205 RequestKind::Subscribe(fake_id.clone()),
206 flags.clone(),
207 )),
208 Message::Request(Request::new(
209 id.clone(),
210 request_id,
211 RequestKind::Query(fake_id.clone()),
212 flags.clone(),
213 )),
214 Message::Request(Request::new(
215 id.clone(),
216 request_id,
217 RequestKind::PushData(id.clone(), vec![page.clone()]),
218 flags.clone(),
219 )),
220 Message::Response(Response::new(
221 id.clone(),
222 request_id,
223 ResponseKind::Status(Status::Ok),
224 flags.clone(),
225 )),
226 Message::Response(Response::new(
228 id.clone(),
229 request_id,
230 ResponseKind::NodesFound(
231 fake_id.clone(),
232 vec![(
233 fake_id.clone(),
234 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080).into(),
235 pub_key.clone(),
236 )],
237 ),
238 flags.clone(),
239 )),
240 Message::Response(Response::new(
241 id.clone(),
242 request_id,
243 ResponseKind::ValuesFound(fake_id.clone(), vec![page.clone()]),
244 flags.clone(),
245 )),
246 Message::Response(Response::new(
247 id.clone(),
248 request_id,
249 ResponseKind::NoResult,
250 flags.clone(),
251 )),
252 Message::Response(Response::new(
253 id.clone(),
254 request_id,
255 ResponseKind::PullData(fake_id.clone(), vec![page.clone()]),
256 flags.clone(),
257 )),
258 ];
259
260 for message in messages {
261 let mut b: Base = message.clone().into();
263 let n = b
265 .encode(Some(&pri_key), None, &mut buff)
266 .expect("error encoding message");
267 let (mut d, m) = Base::parse(&buff[..n], |_id| Some(pub_key.clone()), |_id| None)
269 .expect("error parsing message");
270
271 assert_eq!(n, m);
272
273 d.raw = None;
274 b.raw = None;
275
276 assert_eq!(b, d);
277
278 let message2 = Message::convert(d, |_id| Some(pub_key.clone()))
280 .expect("error converting base object to message");
281
282 assert_eq!(message, message2);
283
284 assert_eq!(message.request_id(), message2.request_id());
285 }
286 }
287}