[pbs-devel] [PATCH xtermjs 3/3] termproxy: rewrite read_ticket_line
Dominik Csapak
d.csapak at proxmox.com
Mon Feb 1 08:55:18 CET 2021
since we cannot accept a std TcpStream from a mio::net::TcpListener
anymore, we cannot use set_read_timeout here
instead implement the readloop as a mio poll loop similar
to listen_and_accept, otherwise termproxy will busy loop and
consume 100% of a single core during authentication
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
src/main.rs | 43 ++++++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 07fa1a8..21bd066 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -92,19 +92,40 @@ fn read_ticket_line(
buf: &mut ByteBuffer,
timeout: Duration,
) -> TicketResult {
- let now = Instant::now();
- while !&buf[..].contains(&b'\n') {
- if buf.is_full() || now.elapsed() >= timeout {
- io_bail!("authentication data is incomplete: {:?}", &buf[..]);
- }
- match buf.read_from(stream) {
- Ok(n) => {
- if n == 0 {
- io_bail!("connection closed before authentication");
+
+ let mut poll = Poll::new()?;
+ poll.registry().register(stream, Token(0), Interest::READABLE)?;
+ let mut events = Events::with_capacity(1);
+ let mut timeout = timeout;
+
+ loop {
+ let now = Instant::now();
+ poll.poll(&mut events, Some(timeout))?;
+ let elapsed = now.elapsed();
+ if !events.is_empty() {
+ match buf.read_from(stream) {
+ Ok(n) => {
+ if n == 0 {
+ io_bail!("connection closed before authentication");
+ }
}
+ Err(err) if err.kind() == ErrorKind::WouldBlock => {}
+ Err(err) => return Err(err),
}
- Err(err) if err.kind() == ErrorKind::WouldBlock => {}
- Err(err) => return Err(err),
+
+ if buf[..].contains(&b'\n') {
+ break;
+ }
+
+ if buf.is_full() {
+ io_bail!("authentication data is incomplete: {:?}", &buf[..]);
+ }
+ }
+
+ if timeout >= elapsed {
+ timeout -= elapsed;
+ } else {
+ io_bail!("timed out");
}
}
--
2.20.1
More information about the pbs-devel
mailing list