From 65aacab48ff91de2704971d7e3d9c96837a365f1 Mon Sep 17 00:00:00 2001 From: ketmar Date: Wed, 5 Jun 2024 07:02:52 +0000 Subject: [PATCH] backend/net: try to prevent hangup on conntection/read failure FossilOrigin-Name: 6f86b22a2054e73a43b36547d92f1e6489413460170e50affecae5cd60e5cfb0 --- chibackend/net/linesocket.d | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/chibackend/net/linesocket.d b/chibackend/net/linesocket.d index 8e39396..5526ca6 100644 --- a/chibackend/net/linesocket.d +++ b/chibackend/net/linesocket.d @@ -51,7 +51,7 @@ private: import core.stdc.stdlib : realloc; enum delta = 8192; auto nlen = rdbufsize+delta; - if (nlen >= 2*1024*1024) { freeRdBuf(); throw new Exception("line too long"); } + if (nlen >= 65536) { freeRdBuf(); throw new Exception("line too long"); } auto nb = cast(char*)realloc(cast(void*)rdbufp, nlen); if (nb is null) { freeRdBuf(); import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); } rdbufp = cast(usize)nb; @@ -142,6 +142,7 @@ public: if (vdata.length == 0) return; //auto dataanchor = data; // 'cause we may get data which requires pointer to head const(char)[] data = cast(const(char)[])vdata; // arg is not modified, and properly anchored + int againsLeft = 6; for (;;) { static if (full) { if (data.length <= 1) break; @@ -151,7 +152,10 @@ public: auto sd = sk.send(data, cast(SocketFlags)(MSG_NOSIGNAL|0x8000/*MSG_MORE*/)); } if (sd <= 0) { - if (isErrorAgain(sd)) continue; + if (isErrorAgain(sd)) { + againsLeft -= 1; + if (againsLeft != 0) continue; + } abort(doshutdown:false); import std.conv : to; throw new Exception("send error ("~sd.to!string~")"); @@ -161,7 +165,10 @@ public: while (data.length) { auto sd = sk.send(data, cast(SocketFlags)(MSG_NOSIGNAL)); if (sd <= 0) { - if (isErrorAgain(sd)) continue; + if (isErrorAgain(sd)) { + againsLeft -= 1; + if (againsLeft != 0) continue; + } abort(doshutdown:false); import std.conv : to; throw new Exception("send error ("~sd.to!string~")"); @@ -278,6 +285,7 @@ public: } } // no buffered line, get more data + int againsLeft = 6; for (;;) { assert(rdbufused <= rdbufsize); if (rdbufused >= rdbufsize) growRdBuf(); @@ -288,8 +296,11 @@ public: abort(doshutdown:false); throw new Exception("read error (connection closed)"); } - if (rc <= 0) { - if (isErrorAgain(rc)) continue; + if (rc < 0) { + if (isErrorAgain(rc)) { + againsLeft -= 1; + if (againsLeft != 0) continue; + } import std.conv : to; abort(doshutdown:false); throw new Exception("read error ("~rc.to!string~")"); -- 2.11.4.GIT