requests.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //! Request generation based on the user’s input arguments.
  2. use dns::Labels;
  3. use crate::connect::TransportType;
  4. use crate::resolve::Resolver;
  5. use crate::txid::TxidGenerator;
  6. /// All the information necessary to generate requests for one or more
  7. /// queries, nameservers, or transport types.
  8. #[derive(PartialEq, Debug)]
  9. pub struct RequestGenerator {
  10. /// The input parameter matrix.
  11. pub inputs: Inputs,
  12. /// How to generate transaction IDs.
  13. pub txid_generator: TxidGenerator,
  14. /// Whether to OPT in to DNS extensions.
  15. pub edns: UseEDNS,
  16. /// Other weird protocol options.
  17. pub protocol_tweaks: ProtocolTweaks,
  18. }
  19. /// Which things the user has specified they want queried.
  20. #[derive(PartialEq, Debug, Default)]
  21. pub struct Inputs {
  22. /// The list of domain names to query.
  23. pub domains: Vec<Labels>,
  24. /// The list of DNS record types to query for.
  25. pub types: Vec<u16>,
  26. /// The list of DNS classes to query for.
  27. pub classes: Vec<dns::QClass>,
  28. /// The list of resolvers to send queries to.
  29. pub resolvers: Vec<Resolver>,
  30. /// The list of transport types to send queries over.
  31. pub transport_types: Vec<TransportType>,
  32. }
  33. /// Weird protocol options that are allowed by the spec but are not common.
  34. #[derive(PartialEq, Debug, Default, Copy, Clone)]
  35. pub struct ProtocolTweaks {
  36. /// Set the `AA` (Authoritative Answer) flag in the header of each request.
  37. pub set_authoritative_flag: bool,
  38. /// Set the `AD` (Authentic Data) flag in the header of each request.
  39. pub set_authentic_flag: bool,
  40. /// Set the `CD` (Checking Disabled) flag in the header of each request.
  41. pub set_checking_disabled_flag: bool,
  42. }
  43. /// Whether to send or display OPT packets.
  44. #[derive(PartialEq, Debug, Copy, Clone)]
  45. pub enum UseEDNS {
  46. /// Do not send an OPT query in requests, and do not display them.
  47. Disable,
  48. /// Send an OPT query in requests, but hide the result. This is the
  49. /// default, because the information is usually not useful to the user.
  50. SendAndHide,
  51. /// Send an OPT query in requests, _and_ display any OPT records in the
  52. /// response we receive.
  53. SendAndShow,
  54. }
  55. impl RequestGenerator {
  56. /// Iterate through the inputs matrix, returning pairs of DNS requests and
  57. /// the details of the transport to send them down.
  58. pub fn generate(self) -> Vec<(dns::Request, Box<dyn dns_transport::Transport>)> {
  59. let nameservers = self.inputs.resolvers.into_iter()
  60. .map(|e| e.lookup().expect("Failed to get nameserver").expect("No nameserver found"))
  61. .collect::<Vec<_>>();
  62. let mut requests = Vec::new();
  63. for domain in &self.inputs.domains {
  64. for qtype in self.inputs.types.iter().copied() {
  65. for qclass in self.inputs.classes.iter().copied() {
  66. for nameserver in &nameservers {
  67. for transport_type in &self.inputs.transport_types {
  68. let transaction_id = self.txid_generator.generate();
  69. let mut flags = dns::Flags::query();
  70. self.protocol_tweaks.set_request_flags(&mut flags);
  71. let mut additional = None;
  72. if self.edns.should_send() {
  73. additional = Some(dns::Request::additional_record());
  74. }
  75. let query = dns::Query { qname: domain.clone(), qtype, qclass };
  76. let request = dns::Request { transaction_id, flags, query, additional };
  77. let transport = transport_type.make_transport(nameserver.clone());
  78. requests.push((request, transport));
  79. }
  80. }
  81. }
  82. }
  83. }
  84. requests
  85. }
  86. }
  87. impl UseEDNS {
  88. /// Whether the user wants to send OPT records.
  89. pub fn should_send(self) -> bool {
  90. self != Self::Disable
  91. }
  92. /// Whether the user wants to display sent OPT records.
  93. pub fn should_show(self) -> bool {
  94. self == Self::SendAndShow
  95. }
  96. }
  97. impl ProtocolTweaks {
  98. pub fn set_request_flags(self, flags: &mut dns::Flags) {
  99. if self.set_authoritative_flag {
  100. flags.authoritative = true;
  101. }
  102. if self.set_authentic_flag {
  103. flags.authentic_data = true;
  104. }
  105. if self.set_checking_disabled_flag {
  106. flags.checking_disabled = true;
  107. }
  108. }
  109. }