Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ Individuals

* Jean-Frédéric Clere <jfclere apache.org> <jfclere gmail.com>
* Tarek Ibrahim <tareki pulsarxtech.com> <t1br4h1m gmail.com>
* Alexander Gerasimov <codeguard gmail.com> <codeit.guru>


15 changes: 15 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ mod_http3 changes
Changes are listed most recent first.
Security-related entries always appear at the top of their release block.

v0.0.71 (2026-10-11)
--------------------
*) Fixed an event-thread spin while a client holds its flow-control window
shut: a blocked stream is now blocked again each time nghttp3 offers it.
[Alexander Gerasimov <codeguard gmail.com>]

*) Fixed a graceful restart that never ended: a handshake still pending
when the child started to drain did not finish or time out, so the old
child kept its connection count and the port.
[Alexander Gerasimov <codeguard gmail.com>]

*) Fixed a heap race that crashed the child: worker threads and the event
thread allocated from one session allocator that had no mutex.
[Alexander Gerasimov <codeguard gmail.com>]

v0.0.70 (2026-09-06)
--------------------
*) SECURITY: Updated the httpd submodule so mpm_event tolerates a connection
Expand Down
4 changes: 2 additions & 2 deletions mod_http3/include/h3_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@

#define MOD_HTTP3_VERSION_MAJOR 0
#define MOD_HTTP3_VERSION_MINOR 0
#define MOD_HTTP3_VERSION_PATCH 70
#define MOD_HTTP3_VERSION_PATCH 71

// Construct a 24-bit packed version number from major, minor and patch. Version 1.2.3 becomes 0x010203.
#define MOD_HTTP3_MAKE_VERSION(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch))

#define MOD_HTTP3_VERSION MOD_HTTP3_MAKE_VERSION(MOD_HTTP3_VERSION_MAJOR, MOD_HTTP3_VERSION_MINOR, MOD_HTTP3_VERSION_PATCH)

#define MOD_HTTP3_VERSION_STRING "0.0.70"
#define MOD_HTTP3_VERSION_STRING "0.0.71"

#endif /* H3_VERSION_H */
9 changes: 9 additions & 0 deletions mod_http3/src/h3_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@ static apr_status_t spawn_serviced_session(h3_io_t* io, h3q_conn* conn)
}
apr_allocator_owner_set(allocator, session_pool);
apr_pool_tag(session_pool, "h3_session");
/* Workers allocate from stream subpools while this thread makes its own: share the allocator safely. */
apr_thread_mutex_t* alloc_mutex = NULL;
if (apr_thread_mutex_create(&alloc_mutex, APR_THREAD_MUTEX_DEFAULT, session_pool) != APR_SUCCESS)
{
apr_pool_destroy(session_pool);
h3q_conn_free(conn);
return APR_EGENERAL;
}
apr_allocator_mutex_set(allocator, alloc_mutex);

h3_session* session = NULL;
if (h3_session_create(&session, io->server, conn, session_pool) != APR_SUCCESS)
Expand Down
5 changes: 3 additions & 2 deletions mod_http3/src/h3_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,14 @@ void flush_nghttp3(h3_session* session)
nghttp3_conn_add_ack_offset(session->ngh3, sid, res.accepted);
if (res.blocked)
{
/* Send buffer full: skip this stream instead of busy-looping on the same vec. */
/* Send buffer full: skip this stream instead of busy-looping on the same vec.
* Block it again every time: resume_stream reschedules a blocked stream. */
if (!h3s->write_blocked)
{
h3s->write_blocked = 1;
session->blocked_streams++;
nghttp3_conn_block_stream(session->ngh3, sid);
}
nghttp3_conn_block_stream(session->ngh3, sid);
continue;
}
}
Expand Down
4 changes: 4 additions & 0 deletions mod_http3/src/h3_threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ void* APR_THREAD_FUNC h3_event_thread(apr_thread_t* thread, void* data)
h3q_conn_free(conn);
}
}
}
if (io->thread_running)
{
/* Also while draining: a pending handshake counts as an MPM connection, so it must finish or time out. */
progress_pending_handshakes(io);
}

Expand Down
Loading