From 08b2de406a45f98cc2b46a35719f4c9d1a87c1b5 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Sat, 3 Oct 2020 21:30:57 +0200 Subject: ssh/tomsg_clientlib: Fix stuck-data bug in tomsg_next_event The issue was that I have too many buffering layers. The bug occurred when the sshnc layer had received some amount of data, some of which (but not all of which) was passed on to tomsg_clientlib via sshnc_maybe_recv in receive_more_data. If the data that _was_ passed on did not constitute a full event, tomsg_clientlib did not ask for more data from the sshnc layer; it would only get received the next time there was actual data on the _socket_, at which point poll(2) would ensure the whole chain gets looped through another time. --- ssh/tomsg_clientlib.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ssh/tomsg_clientlib.c b/ssh/tomsg_clientlib.c index df22a1e..260b785 100644 --- a/ssh/tomsg_clientlib.c +++ b/ssh/tomsg_clientlib.c @@ -938,12 +938,18 @@ enum tomsg_retval tomsg_next_event(struct tomsg_client *client, struct tomsg_eve enum tomsg_retval ret = find_handle_next_line(client, eventp); if (ret != TOMSG_ERR_AGAIN) return ret; - // Otherwise, try to receive more data. - ret = receive_more_data(client); - if (ret != TOMSG_OK) return ret; - - // And then handle any line that might be completed at this point. - return find_handle_next_line(client, eventp); + // Otherwise, try to receive more data until either there is no more data + // anymore, or we have a complete event. + while (true) { + ret = receive_more_data(client); + if (ret != TOMSG_OK) return ret; + + // Handle any line that might be completed at this point. If that + // produces an event or an error, return it; otherwise loop and receive + // more data. + ret = find_handle_next_line(client, eventp); + if (ret != TOMSG_ERR_AGAIN) return ret; + } } #define SEND_FMT0(client, tag, fmt) do { \ -- cgit v1.2.3-70-g09d2