Commit 5c3745f5 authored by jan.koester's avatar jan.koester
Browse files

test

parent 7fba0f07
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
libnetplus (20260404+8) unstable; urgency=medium

  * Fix QUIC stream limit exhaustion: increase initial_max_streams from 100 to 10M
  * Auto-cleanup completed streams and send MAX_STREAMS frames to replenish peer budget
  * Server sends MAX_STREAMS(bidi/uni) when peer-initiated streams are fully closed

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 23:00:00 +0200

libnetplus (20260404+7) unstable; urgency=medium

  * Remove [QUIC] server-side Initial/ServerHello debug logging
+57 −2
Original line number Diff line number Diff line
@@ -2298,7 +2298,7 @@ std::vector<uint8_t> quic::buildTransportParameters() {
    // initial_max_streams_bidi (0x08)
    params.push_back(0x08);
    uint8_t max_streams_buf[8];
    size_t max_streams_len = encodeVarInt(100, max_streams_buf);
    size_t max_streams_len = encodeVarInt(10000000, max_streams_buf);
    uint8_t max_streams_len_buf[8];
    size_t max_streams_len_size = encodeVarInt(max_streams_len, max_streams_len_buf);
    params.insert(params.end(), max_streams_len_buf, max_streams_len_buf + max_streams_len_size);
@@ -3684,6 +3684,36 @@ void quic::sendStreamData(uint64_t stream_id, const std::vector<uint8_t>& data,
done:
    if (fin) {
        stream.send_fin = true;
        // Auto-cleanup: both sides FIN'd → erase stream & replenish peer's stream budget
        if (stream.recv_fin) {
            bool peer_bidi = _is_server ? (stream_id % 4 == 0) : (stream_id % 4 == 1);
            bool peer_uni  = _is_server ? (stream_id % 4 == 2) : (stream_id % 4 == 3);
            _streams.erase(stream_id);
            if (peer_bidi) {
                _max_streams_bidi_local++;
                // Send MAX_STREAMS(bidi) to allow peer to open more streams
                std::vector<uint8_t> ms_frame;
                ms_frame.push_back(0x12);
                uint8_t ms_buf[8];
                size_t ms_bytes = encodeVarInt(_max_streams_bidi_local, ms_buf);
                ms_frame.insert(ms_frame.end(), ms_buf, ms_buf + ms_bytes);
                std::vector<uint8_t> ms_pkt = buildShortHeaderPacket(ms_frame);
                const uint8_t* ms_hp = _is_server ? _app_hp_server : _app_hp_client;
                applyHeaderProtection(ms_pkt, ms_hp);
                sendPacket(ms_pkt.data(), ms_pkt.size());
            } else if (peer_uni) {
                _max_streams_uni_local++;
                std::vector<uint8_t> ms_frame;
                ms_frame.push_back(0x13);
                uint8_t ms_buf[8];
                size_t ms_bytes = encodeVarInt(_max_streams_uni_local, ms_buf);
                ms_frame.insert(ms_frame.end(), ms_buf, ms_buf + ms_bytes);
                std::vector<uint8_t> ms_pkt = buildShortHeaderPacket(ms_frame);
                const uint8_t* ms_hp = _is_server ? _app_hp_server : _app_hp_client;
                applyHeaderProtection(ms_pkt, ms_hp);
                sendPacket(ms_pkt.data(), ms_pkt.size());
            }
        }
    }
}

@@ -4982,9 +5012,34 @@ void quic::closeStream(uint64_t stream_id) {
        stream.send_fin = true;
    }
    
    // If both sides have sent FIN, remove stream
    // If both sides have sent FIN, remove stream and replenish peer's budget
    if (stream.recv_fin && stream.send_fin) {
        bool peer_bidi = _is_server ? (stream_id % 4 == 0) : (stream_id % 4 == 1);
        bool peer_uni  = _is_server ? (stream_id % 4 == 2) : (stream_id % 4 == 3);
        _streams.erase(it);
        if (peer_bidi) {
            _max_streams_bidi_local++;
            std::vector<uint8_t> ms_frame;
            ms_frame.push_back(0x12);
            uint8_t ms_buf[8];
            size_t ms_bytes = encodeVarInt(_max_streams_bidi_local, ms_buf);
            ms_frame.insert(ms_frame.end(), ms_buf, ms_buf + ms_bytes);
            std::vector<uint8_t> ms_pkt = buildShortHeaderPacket(ms_frame);
            const uint8_t* ms_hp = _is_server ? _app_hp_server : _app_hp_client;
            applyHeaderProtection(ms_pkt, ms_hp);
            sendPacket(ms_pkt.data(), ms_pkt.size());
        } else if (peer_uni) {
            _max_streams_uni_local++;
            std::vector<uint8_t> ms_frame;
            ms_frame.push_back(0x13);
            uint8_t ms_buf[8];
            size_t ms_bytes = encodeVarInt(_max_streams_uni_local, ms_buf);
            ms_frame.insert(ms_frame.end(), ms_buf, ms_buf + ms_bytes);
            std::vector<uint8_t> ms_pkt = buildShortHeaderPacket(ms_frame);
            const uint8_t* ms_hp = _is_server ? _app_hp_server : _app_hp_client;
            applyHeaderProtection(ms_pkt, ms_hp);
            sendPacket(ms_pkt.data(), ms_pkt.size());
        }
    }
}

+4 −4
Original line number Diff line number Diff line
@@ -832,10 +832,10 @@ namespace netplus {
		uint64_t _data_recv = 0;

		// Stream count limits (MAX_STREAMS)
		uint64_t _max_streams_bidi_local = 100;   // we allow peer to open
		uint64_t _max_streams_bidi_remote = 100;  // peer allows us to open
		uint64_t _max_streams_uni_local = 100;
		uint64_t _max_streams_uni_remote = 100;
		uint64_t _max_streams_bidi_local = 10000000;   // we allow peer to open
		uint64_t _max_streams_bidi_remote = 10000000;  // peer allows us to open
		uint64_t _max_streams_uni_local = 10000000;
		uint64_t _max_streams_uni_remote = 10000000;
		uint64_t _streams_bidi_opened = 0;        // streams we opened
		uint64_t _streams_uni_opened = 0;
		uint64_t _peer_streams_bidi_opened = 0;   // streams peer opened