Find the IP address of a given host name Uses CACHE to store previous lookups, and uses the DNS server last added to SERVERS.
(name: &str)
| 148 | /// Uses CACHE to store previous lookups, and uses the DNS server last |
| 149 | /// added to SERVERS. |
| 150 | pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> { |
| 151 | // Check the cache |
| 152 | { |
| 153 | let cache = CACHE.read(); |
| 154 | if let Some(addr) = cache.get(name) { |
| 155 | // Here could check expiry time |
| 156 | return Ok(addr.clone()); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // Get the IP address of a DNS server |
| 161 | let dns_address = { |
| 162 | let servers = SERVERS.read(); |
| 163 | match servers.last() { |
| 164 | Some(addr) => addr.clone(), |
| 165 | None => {return Err(ResponseCode::NotImplemented);} |
| 166 | } |
| 167 | }; |
| 168 | |
| 169 | let server = IpEndpoint::new(dns_address, DNS_PORT); |
| 170 | |
| 171 | // Get a local port for the connection |
| 172 | let local_port = crate::ephemeral_port_number(); |
| 173 | let client = IpEndpoint::new(IpAddress::Unspecified, local_port); |
| 174 | |
| 175 | let query = Message::query(name, QueryType::A, QueryClass::IN); |
| 176 | |
| 177 | // Add the UDP socket to the network interface |
| 178 | let udp_handle = { |
| 179 | let udp_rx_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 2048]); |
| 180 | let udp_tx_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 2048]); |
| 181 | let udp_socket = UdpSocket::new(udp_rx_buffer, udp_tx_buffer); |
| 182 | |
| 183 | let mut some_interface = INTERFACE.write(); |
| 184 | let interface = (*some_interface).as_mut().unwrap(); |
| 185 | interface.add_socket(udp_socket) |
| 186 | }; |
| 187 | |
| 188 | #[derive(Debug)] |
| 189 | enum State { Bind, Query, Response } |
| 190 | let mut state = State::Bind; |
| 191 | |
| 192 | // Don't keep a reference to INTERFACE because this thread |
| 193 | // is interleaved with threads servicing other requests. |
| 194 | loop { |
| 195 | { |
| 196 | // Get a lock on the INTERFACE |
| 197 | let mut some_interface = INTERFACE.write(); |
| 198 | let interface = (*some_interface).as_mut().unwrap(); |
| 199 | |
| 200 | if let Err(e) = interface.poll(Instant::from_micros(time::microseconds_monotonic() as i64)) { |
| 201 | println!("Network Error: {}", e); |
| 202 | return Err(ResponseCode::UnknownError); |
| 203 | } |
| 204 | |
| 205 | let socket = interface.get_socket::<UdpSocket>(udp_handle); |
| 206 | |
| 207 | state = match state { |
no test coverage detected