Commit a2567cca authored by jan.koester's avatar jan.koester
Browse files

tls: propagate Note from WAIT_CCS/WAIT_FIN instead of returning

When the client's CCS or Finished record had not arrived yet, the TLS 1.2
server handshake caught the Note from readTlsRecordAsync() and returned
normally. The event loops' handshake loop only stops on a Note, so it
called handshake_after_accept() again forever without ever reading the
socket: one worker at 100% CPU per such connection, holding event_mutex
(which also blocks the idle reaper). Enough of them hang the server.

Triggered by any TLS 1.2 client whose second flight is split across
segments (CKE / CCS / Finished arriving separately).

Co-Authored-By: default avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 532c7a30
Loading
Loading
Loading
Loading
+7 −10
Changes for src/crypto/tls.cpp: 7 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -1066,9 +1066,11 @@ namespace netplus {
                    rec = readTlsRecordAsync();
                } catch (netplus::NetException& e) {
                    if (e.getErrorType() == netplus::NetException::Note) {
    #if SSL_DEBUG
    #endif
                        return;
                        // CCS not here yet: propagate the Note so the event loop
                        // stops calling us and re-arms for EPOLLIN. A plain return
                        // looks like progress and the caller's handshake loop spins
                        // forever without ever reading the socket again.
                        throw;
                    }
                    TLSDBG("readTlsRecordAsync ERROR");
                    throw;
@@ -1094,13 +1096,8 @@ namespace netplus {
            case HsState::WAIT_FIN: {
                if (!aes_recv) throwSSL(NetException::Error, "WAIT_FIN but AES not initialized");

                std::vector<uint8_t> finRec;
                try {
                    finRec = readTlsRecordAsync();
                } catch (NetException& e) {
                    if (e.getErrorType() == NetException::Note) return;
                    throw;
                }
                // A Note (Finished not here yet) must propagate -- see WAIT_CCS.
                std::vector<uint8_t> finRec = readTlsRecordAsync();

                if (finRec.size() < 5 + 16 || finRec[0] != 0x16)
                    throwSSL(NetException::Error, "Expected Finished handshake record");