aboutsummaryrefslogtreecommitdiff
path: root/doh
diff options
context:
space:
mode:
authorMike Yu <yumike@google.com>2022-02-14 13:36:33 +0800
committerMike Yu <yumike@google.com>2022-02-23 15:47:17 +0800
commitf696ba345dc1d323459d55aea88fed583a581232 (patch)
tree0cc3d6d6bb9afd2023d134c11f616a60471a5943 /doh
parent78f82d67354975a794b6477c45fe6bc6fb9a1931 (diff)
downloadDnsResolver-f696ba345dc1d323459d55aea88fed583a581232.tar.gz
DoH: Don't call handle_draining() more than once
Calling handle_draining() is effective only for the first time. Subsequent calls are not necessary because all of the relative channels are already closed. Bug: 215818810 Test: cd packages/modules/DnsResolver && atest Test: checked the log that "draining on network" is printed only once Change-Id: Ifae32daff39fc86f40550005f35f544b449dd37e
Diffstat (limited to 'doh')
-rw-r--r--doh/connection/driver.rs20
1 files changed, 11 insertions, 9 deletions
diff --git a/doh/connection/driver.rs b/doh/connection/driver.rs
index d4c5bd5d..50d0928b 100644
--- a/doh/connection/driver.rs
+++ b/doh/connection/driver.rs
@@ -87,6 +87,12 @@ struct Driver {
// moves of the driver.
buffer: Box<[u8; MAX_UDP_PACKET_SIZE]>,
net_id: u32,
+ // Used to check if the connection has entered closing or draining state. A connection can
+ // enter closing state if the sender of request_rx's channel has been dropped.
+ // Note that we can't check if a receiver is dead without potentially receiving a message, and
+ // if we poll on a dead receiver in a select! it will immediately return None. As a result, we
+ // need this to gate whether or not to include .recv() in our select!
+ closing: bool,
}
struct H3Driver {
@@ -95,10 +101,6 @@ struct H3Driver {
// This value holds a peeked request in that case, waiting for
// transmission to become possible.
buffered_request: Option<Request>,
- // We can't check if a receiver is dead without potentially receiving a message, and if we poll
- // on a dead receiver in a select! it will immediately return None. As a result, we need this
- // to gate whether or not to include .recv() in our select!
- closing: bool,
h3_conn: h3::Connection,
requests: HashMap<u64, Request>,
streams: HashMap<u64, Stream>,
@@ -139,6 +141,7 @@ impl Driver {
socket,
buffer: Box::new([0; MAX_UDP_PACKET_SIZE]),
net_id,
+ closing: false,
}
}
@@ -168,8 +171,7 @@ impl Driver {
}
fn handle_draining(&mut self) {
- if self.quiche_conn.is_draining() {
- // TODO: avoid running the code below more than once.
+ if self.quiche_conn.is_draining() && !self.closing {
// TODO: Also log local_error() once Quiche 0.10.0 is available.
debug!(
"Connection {} is draining on network {}, peer_error={:x?}",
@@ -187,6 +189,7 @@ impl Driver {
// TODO: re-issue the outstanding DNS requests, such as passing H3Driver.requests
// along with Status::Dead to the `Network` that can re-issue the DNS requests.
while self.request_rx.try_recv().is_ok() {}
+ self.closing = true;
}
}
@@ -252,7 +255,6 @@ impl H3Driver {
Self {
driver,
h3_conn,
- closing: false,
requests: HashMap::new(),
streams: HashMap::new(),
buffered_request: None,
@@ -287,7 +289,7 @@ impl H3Driver {
select! {
// Only attempt to enqueue new requests if we have no buffered request and aren't
// closing
- msg = self.driver.request_rx.recv(), if !self.closing && self.buffered_request.is_none() => {
+ msg = self.driver.request_rx.recv(), if !self.driver.closing && self.buffered_request.is_none() => {
match msg {
Some(request) => self.handle_request(request)?,
None => self.shutdown(true, b"DONE").await?,
@@ -470,7 +472,7 @@ impl H3Driver {
);
self.driver.request_rx.close();
while self.driver.request_rx.recv().await.is_some() {}
- self.closing = true;
+ self.driver.closing = true;
if send_goaway {
self.h3_conn.send_goaway(&mut self.driver.quiche_conn, 0)?;
}