From: David Woodhouse Date: Thu, 15 Apr 2021 15:36:15 +0000 (+0100) Subject: Fix -EAGAIN on writing DTLS socket for PPP mainloop X-Git-Tag: v8.20~289 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=68bf482f04e94c9482513dc92e5228840303009f;p=users%2Fdwmw2%2Fopenconnect.git Fix -EAGAIN on writing DTLS socket for PPP mainloop If the socket sndbuf is full, we fail to send a packet. This should actually happen less often for UDP than it does for TCP because of the lack of back pressure from the peer, but it's still a fairly normal condition and needs to be handled properly. The correct handling is basically to do nothing and wait for the jam to clear, unless it's been *so* long that DPD has caused us to think the peer is dead, or we need a rekey (which we do be reconnecting the transport channel). The ka_stalled_action() function exists specifically to handle this case, and returns one of KA_NONE, KA_DPD_DEAD or KA_REKEY. There's no ponit in it returning KA_DPD or KA_KEEPALIVE like the normal keepalive_action() does because the point here is that we *can't* send anything at the moment anyway. The problem here is that the PPP mainloop doesn't handle those three cases correctly, and KA_REKEY and KA_NONE were just falling through to end up at the fatal error condition for a *short* write, which should never happen. I went too far when commenting out the cut and pasted mainloop to create ppp_mainloop. Fix KA_REKEY to do a reconnect, and KA_NONE to just return work_done as it should. Fixes: a47406b43 ("add support for PPP-based protocols") Signed-off-by: David Woodhouse --- diff --git a/ppp.c b/ppp.c index 1377270f..a552f41a 100644 --- a/ppp.c +++ b/ppp.c @@ -1256,11 +1256,12 @@ int ppp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) case KA_DPD_DEAD: goto peer_dead; case KA_REKEY: -// goto do_rekey; + goto do_reconnect; case KA_NONE: -// return work_done; + return work_done; default: - /* This should never happen */ + /* This can never happen because ka_stalled_action() + * always returns one of the above. */ ; } }