xref: /aosp_15_r20/tools/netsim/rust/http-proxy/src/dns_manager.rs (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2024 Google LLC
2*cf78ab8cSAndroid Build Coastguard Worker //
3*cf78ab8cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*cf78ab8cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*cf78ab8cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*cf78ab8cSAndroid Build Coastguard Worker //
7*cf78ab8cSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*cf78ab8cSAndroid Build Coastguard Worker //
9*cf78ab8cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*cf78ab8cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*cf78ab8cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cf78ab8cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*cf78ab8cSAndroid Build Coastguard Worker // limitations under the License.
14*cf78ab8cSAndroid Build Coastguard Worker 
15*cf78ab8cSAndroid Build Coastguard Worker /// This module provides a reverse-dns function that caches the domain
16*cf78ab8cSAndroid Build Coastguard Worker /// name (FQDNs) and IpAddr from DNS answer records.
17*cf78ab8cSAndroid Build Coastguard Worker ///
18*cf78ab8cSAndroid Build Coastguard Worker /// This manager exists for two reasons:
19*cf78ab8cSAndroid Build Coastguard Worker ///
20*cf78ab8cSAndroid Build Coastguard Worker /// 1. RFC2817 Compliance (b/37055721): Requires converting IP address to
21*cf78ab8cSAndroid Build Coastguard Worker /// hostname for HTTP CONNECT requests.
22*cf78ab8cSAndroid Build Coastguard Worker ///
23*cf78ab8cSAndroid Build Coastguard Worker /// 2. Proxy bypass/exclusion list requires matching on host name
24*cf78ab8cSAndroid Build Coastguard Worker /// patterns.
25*cf78ab8cSAndroid Build Coastguard Worker ///
26*cf78ab8cSAndroid Build Coastguard Worker use crate::dns;
27*cf78ab8cSAndroid Build Coastguard Worker use etherparse::{PacketHeaders, PayloadSlice, TransportHeader};
28*cf78ab8cSAndroid Build Coastguard Worker use std::collections::HashMap;
29*cf78ab8cSAndroid Build Coastguard Worker use std::net::IpAddr;
30*cf78ab8cSAndroid Build Coastguard Worker 
31*cf78ab8cSAndroid Build Coastguard Worker pub struct DnsManager {
32*cf78ab8cSAndroid Build Coastguard Worker     map: HashMap<IpAddr, String>,
33*cf78ab8cSAndroid Build Coastguard Worker }
34*cf78ab8cSAndroid Build Coastguard Worker 
35*cf78ab8cSAndroid Build Coastguard Worker impl DnsManager {
36*cf78ab8cSAndroid Build Coastguard Worker     const DNS_PORT: u16 = 53;
37*cf78ab8cSAndroid Build Coastguard Worker 
new() -> Self38*cf78ab8cSAndroid Build Coastguard Worker     pub fn new() -> Self {
39*cf78ab8cSAndroid Build Coastguard Worker         DnsManager { map: HashMap::new() }
40*cf78ab8cSAndroid Build Coastguard Worker     }
41*cf78ab8cSAndroid Build Coastguard Worker 
42*cf78ab8cSAndroid Build Coastguard Worker     /// Add potential DNS entries to the cache.
add_from_packet_headers(&mut self, headers: &PacketHeaders)43*cf78ab8cSAndroid Build Coastguard Worker     pub fn add_from_packet_headers(&mut self, headers: &PacketHeaders) {
44*cf78ab8cSAndroid Build Coastguard Worker         // Check if the packet contains a UDP header
45*cf78ab8cSAndroid Build Coastguard Worker         // with source port from DNS server
46*cf78ab8cSAndroid Build Coastguard Worker         // and DNS answers with A/AAAA records
47*cf78ab8cSAndroid Build Coastguard Worker         if let Some(TransportHeader::Udp(udp_header)) = &headers.transport {
48*cf78ab8cSAndroid Build Coastguard Worker             // with source port from DNS server
49*cf78ab8cSAndroid Build Coastguard Worker             if udp_header.source_port == Self::DNS_PORT {
50*cf78ab8cSAndroid Build Coastguard Worker                 if let PayloadSlice::Udp(ref payload) = headers.payload {
51*cf78ab8cSAndroid Build Coastguard Worker                     // Add any A/AAAA domain names
52*cf78ab8cSAndroid Build Coastguard Worker                     if let Ok(answers) = dns::parse_answers(payload) {
53*cf78ab8cSAndroid Build Coastguard Worker                         for (ip_addr, name) in answers {
54*cf78ab8cSAndroid Build Coastguard Worker                             self.map.insert(ip_addr, name);
55*cf78ab8cSAndroid Build Coastguard Worker                         }
56*cf78ab8cSAndroid Build Coastguard Worker                     }
57*cf78ab8cSAndroid Build Coastguard Worker                 }
58*cf78ab8cSAndroid Build Coastguard Worker             }
59*cf78ab8cSAndroid Build Coastguard Worker         }
60*cf78ab8cSAndroid Build Coastguard Worker     }
61*cf78ab8cSAndroid Build Coastguard Worker 
add_from_ethernet_slice(&mut self, packet: &[u8])62*cf78ab8cSAndroid Build Coastguard Worker     pub fn add_from_ethernet_slice(&mut self, packet: &[u8]) {
63*cf78ab8cSAndroid Build Coastguard Worker         let headers = PacketHeaders::from_ethernet_slice(packet).unwrap();
64*cf78ab8cSAndroid Build Coastguard Worker         self.add_from_packet_headers(&headers);
65*cf78ab8cSAndroid Build Coastguard Worker     }
66*cf78ab8cSAndroid Build Coastguard Worker 
67*cf78ab8cSAndroid Build Coastguard Worker     /// Return a FQDN from a prior DNS response for ip address
get(&self, ip_addr: &IpAddr) -> Option<String>68*cf78ab8cSAndroid Build Coastguard Worker     pub fn get(&self, ip_addr: &IpAddr) -> Option<String> {
69*cf78ab8cSAndroid Build Coastguard Worker         self.map.get(ip_addr).cloned()
70*cf78ab8cSAndroid Build Coastguard Worker     }
71*cf78ab8cSAndroid Build Coastguard Worker 
len(&self) -> usize72*cf78ab8cSAndroid Build Coastguard Worker     pub fn len(&self) -> usize {
73*cf78ab8cSAndroid Build Coastguard Worker         self.map.len()
74*cf78ab8cSAndroid Build Coastguard Worker     }
75*cf78ab8cSAndroid Build Coastguard Worker }
76