1use pharos_proto::{Class, MessageBuilder, Opcode, Section, Type};
2use pharos_server::{Context, Error, Next, Outcome, Plugin, Protocol};
3
4#[derive(Debug)]
6pub struct Any;
7
8impl Plugin for Any {
9 async fn serve<N: Next + Send>(&self, cx: &mut Context<'_>, next: N) -> Outcome {
10 let Some(question) = cx.query.questions().next() else {
11 return next.run(cx).await;
12 };
13 if question.qtype != Type::ANY {
14 return next.run(cx).await;
15 }
16 let result = (|| {
17 let max_size = cx.max_response_size.max(512);
18 if cx.response.capacity() < max_size {
19 if cx.protocol == Protocol::Tcp {
20 cx.response
21 .reserve(max_size.saturating_sub(cx.response.len()));
22 } else {
23 return Err(Error::ResponseBufferTooSmall);
24 }
25 }
26 let mut flags = 0x8000 | (cx.query.flags() & 0x7800);
27 if cx.query.opcode() == Opcode::QUERY {
28 flags |= cx.query.flags() & 0x0110;
29 }
30 let mut builder = MessageBuilder::new(cx.response, max_size, cx.query.id(), flags)
31 .map_err(Error::Build)?;
32 builder
33 .question(question.name, question.qtype, question.qclass)
34 .map_err(Error::Build)?;
35 builder
37 .record(
38 Section::Answer,
39 question.name,
40 Type::HINFO,
41 Class::IN,
42 8482,
43 b"\x0dANY obsoleted\x0cSee RFC 8482",
44 )
45 .map_err(Error::Build)?;
46 let _ = builder.finish();
47 Ok(())
48 })();
49 match result {
50 Ok(()) => Outcome::Response,
51 Err(error) => Outcome::Error(error),
52 }
53 }
54}