1use std::net::{Ipv4Addr, SocketAddrV4};
2
3use smallvec::SmallVec;
4use tl_proto::{Bare, Boxed, BoxedConstructor, TlError, TlPacket, TlRead, TlResult, TlWrite};
5
6use super::HashRef;
7
8#[derive(Clone)]
9pub struct OutgoingPacketContents<'tl> {
10 pub rand1: &'tl [u8],
12 pub from: Option<everscale_crypto::tl::PublicKey<'tl>>,
13 pub messages: OutgoingMessages<'tl>,
14 pub address: AddressList,
15 pub seqno: u64,
16 pub confirm_seqno: u64,
17 pub reinit_dates: Option<ReinitDates>,
18 pub signature: Option<&'tl [u8]>,
19 pub rand2: &'tl [u8],
21}
22
23impl<'tl> TlWrite for OutgoingPacketContents<'tl> {
24 type Repr = Boxed;
25
26 fn max_size_hint(&self) -> usize {
27 4 + 8 + 4 + self.from.max_size_hint()
31 + self.messages.max_size_hint()
32 + self.address.max_size_hint()
33 + 8 + 8 + self.reinit_dates.max_size_hint()
36 + self.signature.max_size_hint()
37 + 4 }
39
40 fn write_to<P>(&self, packet: &mut P)
41 where
42 P: TlPacket,
43 {
44 const DEFAULT_FLAGS: u32 = (0b1 << 4) | (0b1 << 6) | (0b1 << 7);
45
46 let flags = DEFAULT_FLAGS
47 | (self.from.is_some() as u32)
48 | if self.messages.is_single() {
49 0b1 << 2
50 } else {
51 0b1 << 3
52 }
53 | ((self.reinit_dates.is_some() as u32) << 10)
54 | ((self.signature.is_some() as u32) << 11);
55
56 packet.write_u32(IncomingPacketContents::TL_ID); self.rand1.write_to(packet);
58 packet.write_u32(flags);
59 self.from.write_to(packet);
60 self.messages.write_to(packet);
61 self.address.write_to(packet);
62 self.seqno.write_to(packet);
63 self.confirm_seqno.write_to(packet);
64 self.reinit_dates.write_to(packet);
65 self.signature.write_to(packet);
66 self.rand2.write_to(packet);
67 }
68}
69
70#[derive(Copy, Clone)]
71pub enum OutgoingMessages<'a> {
72 Single(&'a [u8]),
73 Pair(&'a [u8]),
74}
75
76impl OutgoingMessages<'_> {
77 #[inline(always)]
78 pub fn is_single(&self) -> bool {
79 matches!(self, Self::Single(_))
80 }
81}
82
83impl<'tl> TlWrite for OutgoingMessages<'tl> {
84 type Repr = Bare;
85
86 #[inline(always)]
87 fn max_size_hint(&self) -> usize {
88 match self {
89 Self::Single(raw) => raw.len(),
90 Self::Pair(raw) => 4 + raw.len(),
91 }
92 }
93
94 #[inline(always)]
95 fn write_to<P>(&self, packet: &mut P)
96 where
97 P: TlPacket,
98 {
99 match self {
100 Self::Single(raw) => packet.write_raw_slice(raw),
101 Self::Pair(raw) => {
102 packet.write_u32(2);
103 packet.write_raw_slice(raw);
104 }
105 }
106 }
107}
108
109#[derive(Clone)]
110pub struct IncomingPacketContents<'tl> {
111 pub from: Option<everscale_crypto::tl::PublicKey<'tl>>,
112 pub from_short: Option<HashRef<'tl>>,
113
114 pub messages: SmallVec<[Message<'tl>; 2]>,
115 pub address: Option<AddressList>,
116
117 pub seqno: Option<u64>,
118 pub confirm_seqno: Option<u64>,
119
120 pub reinit_dates: Option<ReinitDates>,
121
122 pub signature: Option<PacketContentsSignature>,
123}
124
125impl IncomingPacketContents<'_> {
126 const TL_ID: u32 = tl_proto::id!("adnl.packetContents", scheme = "scheme.tl");
127}
128
129impl<'tl> TlRead<'tl> for IncomingPacketContents<'tl> {
130 type Repr = Boxed;
131
132 fn read_from(packet: &'tl [u8], offset: &mut usize) -> TlResult<Self> {
133 #[inline(always)]
134 fn read_optional<'tl, T: TlRead<'tl>, const N: usize>(
135 flags: u32,
136 packet: &'tl [u8],
137 offset: &mut usize,
138 ) -> TlResult<Option<T>> {
139 Ok(if flags & (0b1 << N) != 0 {
140 match T::read_from(packet, offset) {
141 Ok(value) => Some(value),
142 Err(e) => return Err(e),
143 }
144 } else {
145 None
146 })
147 }
148
149 match u32::read_from(packet, offset) {
150 Ok(Self::TL_ID) => {}
151 Ok(_) => return Err(TlError::UnknownConstructor),
152 Err(e) => return Err(e),
153 }
154
155 ok!(<&[u8] as TlRead>::read_from(packet, offset)); let flags_offset = *offset as u16;
158 let flags = ok!(u32::read_from(packet, offset));
159
160 let from = ok!(read_optional::<everscale_crypto::tl::PublicKey, 0>(
161 flags, packet, offset
162 ));
163 let from_short = ok!(read_optional::<HashRef, 1>(flags, packet, offset));
164
165 let message = ok!(read_optional::<Message, 2>(flags, packet, offset));
166 let messages = ok!(read_optional::<SmallVec<[Message<'tl>; 2]>, 3>(
167 flags, packet, offset
168 ));
169
170 let address = ok!(read_optional::<AddressList, 4>(flags, packet, offset));
171 ok!(read_optional::<AddressList, 5>(flags, packet, offset)); let seqno = ok!(read_optional::<u64, 6>(flags, packet, offset));
174 let confirm_seqno = ok!(read_optional::<u64, 7>(flags, packet, offset));
175
176 ok!(read_optional::<u32, 8>(flags, packet, offset)); ok!(read_optional::<u32, 9>(flags, packet, offset)); let reinit_dates = ok!(read_optional::<ReinitDates, 10>(flags, packet, offset));
180
181 let signature = if flags & (0b1 << 11) != 0 {
182 let signature_start = *offset as u16;
183 let signature = ok!(<&[u8]>::read_from(packet, offset));
184 let signature_end = *offset as u16;
185
186 if signature.len() != 64 {
187 return Err(TlError::UnexpectedEof);
188 }
189
190 Some(PacketContentsSignature {
191 signature: signature.try_into().unwrap(),
192 flags_offset,
193 signature_start,
194 signature_end,
195 })
196 } else {
197 None
198 };
199
200 ok!(<&[u8] as TlRead>::read_from(packet, offset)); Ok(Self {
203 from,
204 from_short,
205 messages: match (messages, message) {
206 (Some(messages), None) => messages,
207 (None, Some(message)) => {
208 let mut messages = SmallVec::with_capacity(1);
209 messages.push(message);
210 messages
211 }
212 (Some(mut messages), Some(message)) => {
213 messages.insert(0, message);
214 messages
215 }
216 (None, None) => return Err(TlError::UnexpectedEof),
217 },
218 address,
219 seqno,
220 confirm_seqno,
221 reinit_dates,
222 signature,
223 })
224 }
225}
226
227#[derive(Copy, Clone)]
228pub struct PacketContentsSignature {
229 signature: [u8; 64],
230 flags_offset: u16,
231 signature_start: u16,
232 signature_end: u16,
233}
234
235impl PacketContentsSignature {
236 pub unsafe fn extract<'a>(self, packet: &mut [u8]) -> Option<(&'a [u8], [u8; 64])> {
244 let origin = packet.as_mut_ptr();
245
246 let (signature_len, remaining) = match (packet.len() as u16, self.flags_offset + 1) {
253 (packet_len, flags_offset)
254 if flags_offset < packet_len
255 && self.signature_start < self.signature_end
256 && self.signature_end < packet_len =>
257 {
258 packet[flags_offset as usize] &= 0xf7; (
261 self.signature_end - self.signature_start, packet_len - self.signature_end, )
264 }
265 _ => return None,
266 };
267
268 let src = origin.add(self.signature_end as usize);
269 let dst = origin.add(self.signature_start as usize);
270 std::ptr::copy(src, dst, remaining as usize);
271
272 Some((
277 std::slice::from_raw_parts(origin, packet.len() - signature_len as usize),
278 self.signature,
279 ))
280 }
281}
282
283#[derive(Debug, Copy, Clone, TlWrite, TlRead)]
284#[tl(size_hint = 8)]
285pub struct ReinitDates {
286 pub local: u32,
287 pub target: u32,
288}
289
290#[derive(Debug, Copy, Clone, TlRead, TlWrite)]
291#[tl(boxed, scheme = "scheme.tl")]
292pub enum Message<'tl> {
293 #[tl(id = "adnl.message.answer")]
294 Answer {
295 #[tl(size_hint = 32)]
296 query_id: HashRef<'tl>,
297 answer: &'tl [u8],
298 },
299
300 #[tl(id = "adnl.message.custom")]
301 Custom { data: &'tl [u8] },
302
303 #[tl(id = "adnl.message.confirmChannel", size_hint = 68)]
304 ConfirmChannel {
305 key: HashRef<'tl>,
306 peer_key: HashRef<'tl>,
307 date: u32,
308 },
309
310 #[tl(id = "adnl.message.part")]
311 Part {
312 #[tl(size_hint = 32)]
313 hash: HashRef<'tl>,
314 total_size: u32,
315 offset: u32,
316 data: &'tl [u8],
317 },
318
319 #[tl(id = "adnl.message.createChannel", size_hint = 36)]
320 CreateChannel { key: HashRef<'tl>, date: u32 },
321
322 #[tl(id = "adnl.message.query")]
323 Query {
324 #[tl(size_hint = 32)]
325 query_id: HashRef<'tl>,
326 query: &'tl [u8],
327 },
328
329 #[tl(id = "adnl.message.nop", size_hint = 0)]
330 Nop,
331
332 #[tl(id = "adnl.message.reinit", size_hint = 4)]
333 Reinit { date: u32 },
334}
335
336#[derive(Debug, Copy, Clone)]
337pub struct AddressList {
338 pub address: Option<Address>,
340 pub version: u32,
341 pub reinit_date: u32,
342 pub expire_at: u32,
343}
344
345impl BoxedConstructor for AddressList {
346 const TL_ID: u32 = tl_proto::id!("adnl.addressList", scheme = "scheme.tl");
347}
348
349impl TlWrite for AddressList {
350 type Repr = Bare;
351
352 fn max_size_hint(&self) -> usize {
353 20 + self.address.max_size_hint()
360 }
361
362 fn write_to<P>(&self, packet: &mut P)
363 where
364 P: TlPacket,
365 {
366 u32::write_to(&(self.address.is_some() as u32), packet);
367 self.address.write_to(packet);
368 self.version.write_to(packet);
369 self.reinit_date.write_to(packet);
370 0u32.write_to(packet); self.expire_at.write_to(packet);
372 }
373}
374
375impl<'tl> TlRead<'tl> for AddressList {
376 type Repr = Bare;
377
378 fn read_from(packet: &'tl [u8], offset: &mut usize) -> TlResult<Self> {
379 let address_count = ok!(u32::read_from(packet, offset));
380 let mut address = None;
381 for _ in 0..address_count {
382 let item = ok!(Address::read_from(packet, offset));
383 if address.is_none() {
384 address = Some(item);
385 }
386 }
387
388 let version = ok!(u32::read_from(packet, offset));
389 let reinit_date = ok!(u32::read_from(packet, offset));
390 let _priority = ok!(u32::read_from(packet, offset));
391 let expire_at = ok!(u32::read_from(packet, offset));
392
393 Ok(Self {
394 address,
395 version,
396 reinit_date,
397 expire_at,
398 })
399 }
400}
401
402#[derive(Debug, Copy, Clone, TlRead, TlWrite)]
403#[tl(boxed, id = "adnl.address.udp", scheme = "scheme.tl", size_hint = 8)]
404pub struct Address {
405 pub ip: u32,
406 pub port: u32,
407}
408
409impl From<&SocketAddrV4> for Address {
410 fn from(addr: &SocketAddrV4) -> Self {
411 Self {
412 ip: u32::from_be_bytes(addr.ip().octets()),
413 port: addr.port() as u32,
414 }
415 }
416}
417
418impl From<Address> for SocketAddrV4 {
419 fn from(addr: Address) -> Self {
420 Self::new(Ipv4Addr::from(addr.ip), addr.port as u16)
421 }
422}
423
424#[derive(Debug, Copy, Clone, TlRead, TlWrite)]
425#[tl(boxed, id = "adnl.pong", size_hint = 8, scheme = "scheme.tl")]
426pub struct Pong {
427 pub value: u64,
428}
429
430#[cfg(test)]
431mod tests {
432 use super::*;
433
434 #[test]
435 fn correct_addr_conversion() {
436 let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 123);
437
438 let test = Address::from(&addr);
439 assert_eq!(test.ip, 0x7f000001);
440 assert_eq!(test.port, 123);
441
442 let test = SocketAddrV4::from(test);
443 assert_eq!(test, addr);
444 }
445}