aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-07-24 14:36:36 +0200
committerHimbeer <himbeer@disroot.org>2024-07-24 14:36:36 +0200
commitb0b138343a4edf00bc7aff0e6ea8f4bd17a03904 (patch)
tree47f4e90ca3dac6bfb8abd8c1a6ad92578a61877c
parentb4006f08fa42662006e6ece1d7ce29f59a185175 (diff)
Revert "Handle upstream read timeouts less disruptively"
This reverts commit 7330e326b1f747646257f33bf713876a0d753ca5.
-rw-r--r--src/main.rs92
1 files changed, 17 insertions, 75 deletions
diff --git a/src/main.rs b/src/main.rs
index c3f83e6..d5592c3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
use std::cell::RefCell;
use std::fs::{self, File};
use std::io;
-use std::net::{IpAddr, SocketAddr, UdpSocket};
+use std::net::{IpAddr, SocketAddr, ToSocketAddrs, UdpSocket};
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use std::thread;
@@ -116,14 +116,6 @@ fn main() -> Result<()> {
let sock = UdpSocket::bind("[::]:53")?;
- let uplink_primary = UdpSocket::bind("[::]:0")?;
- uplink_primary.set_read_timeout(Some(UPSTREAM_TIMEOUT))?;
- uplink_primary.connect(UPSTREAM_PRIMARY)?;
-
- let uplink_secondary = UdpSocket::bind("[::]:0")?;
- uplink_secondary.set_read_timeout(Some(UPSTREAM_TIMEOUT))?;
- uplink_secondary.connect(UPSTREAM_SECONDARY)?;
-
loop {
let mut buf = [0; 1024];
let (n, raddr) = sock.recv_from(&mut buf)?;
@@ -131,31 +123,14 @@ fn main() -> Result<()> {
let domain2 = domain.clone();
let sock2 = sock.try_clone()?;
- let uplink_primary2 = uplink_primary.try_clone()?;
- let uplink_secondary2 = uplink_secondary.try_clone()?;
let buf = buf.to_vec();
let leases3 = leases.clone();
- thread::spawn(move || {
- match handle_query(
- &domain2,
- &sock2,
- uplink_primary2,
- uplink_secondary2,
- &buf,
- raddr,
- leases3,
- ) {
+ thread::spawn(
+ move || match handle_query(&domain2, sock2, &buf, raddr, leases3) {
Ok(_) => {}
- Err(e) => {
- match respond_with_error(&sock2, &buf, raddr) {
- Ok(_) => {}
- Err(e) => println!("[warn] {} send error response: {}", raddr, e),
- }
-
- print_query_error(&buf, raddr, e);
- }
- }
- });
+ Err(e) => print_query_error(&buf, raddr, e),
+ },
+ );
}
}
@@ -170,39 +145,6 @@ fn print_query_error(buf: &[u8], raddr: SocketAddr, e: Error) {
}
}
-fn respond_with_error(sock: &UdpSocket, buf: &[u8], raddr: SocketAddr) -> Result<()> {
- let bytes = Bytes::copy_from_slice(buf);
- let msg = Dns::decode(bytes)?;
-
- let resp = Dns {
- id: msg.id,
- flags: Flags {
- qr: true,
- opcode: msg.flags.opcode,
- aa: false,
- tc: false,
- rd: msg.flags.rd,
- ra: true,
- ad: false,
- cd: false,
- rcode: RCode::ServFail,
- },
- questions: Vec::default(),
- answers: Vec::default(),
- authorities: Vec::default(),
- additionals: Vec::default(),
- };
-
- let bytes = resp.encode()?;
-
- let n = sock.send_to(&bytes, raddr)?;
- if n != bytes.len() {
- return Err(Error::PartialSend(bytes.len(), n));
- }
-
- Ok(())
-}
-
fn extract_questions(buf: &[u8]) -> Result<Vec<Question>> {
let bytes = Bytes::copy_from_slice(buf);
let msg = Dns::decode(bytes)?;
@@ -212,9 +154,7 @@ fn extract_questions(buf: &[u8]) -> Result<Vec<Question>> {
fn handle_query(
domain: &Option<Name>,
- sock: &UdpSocket,
- uplink_primary: UdpSocket,
- uplink_secondary: UdpSocket,
+ sock: UdpSocket,
buf: &[u8],
raddr: SocketAddr,
leases: Arc<RwLock<Vec<Lease>>>,
@@ -347,15 +287,12 @@ fn handle_query(
if !msg.questions.is_empty() {
let bytes = msg.encode()?;
- let resp = match upstream_query(uplink_primary, &bytes) {
+ let resp = match upstream_query(UPSTREAM_PRIMARY, &bytes) {
Ok(v) => v,
- Err(e) => match upstream_query(uplink_secondary, &bytes) {
- Ok(v) => {
- println!("[warn] {} primary unavailable: {}", raddr, e);
- v
- }
+ Err(e) => match upstream_query(UPSTREAM_SECONDARY, &bytes) {
+ Ok(v) => v,
Err(e2) => {
- println!("[warn] {} secondary unavailable: {}", raddr, e2);
+ println!("[warn] primary unavailable: {}", e);
return Err(e2);
}
},
@@ -403,7 +340,12 @@ fn handle_query(
Ok(())
}
-fn upstream_query(uplink: UdpSocket, bytes: &[u8]) -> Result<Dns> {
+fn upstream_query<A: ToSocketAddrs>(upstream: A, bytes: &[u8]) -> Result<Dns> {
+ let uplink = UdpSocket::bind("[::]:0")?;
+
+ uplink.set_read_timeout(Some(Duration::from_secs(1)))?;
+ uplink.connect(upstream)?;
+
let n = uplink.send(bytes)?;
if n != bytes.len() {
return Err(Error::PartialSend(bytes.len(), n));