Skip to content

Add: Server-side TLS handshake milestones and timing fixes#12860

Open
bryancall wants to merge 6 commits intoapache:masterfrom
bryancall:server-tls-milestones
Open

Add: Server-side TLS handshake milestones and timing fixes#12860
bryancall wants to merge 6 commits intoapache:masterfrom
bryancall:server-tls-milestones

Conversation

@bryancall
Copy link
Contributor

@bryancall bryancall commented Feb 5, 2026

Description

Add TS_MILESTONE_SERVER_TLS_HANDSHAKE_START and TS_MILESTONE_SERVER_TLS_HANDSHAKE_END milestones to capture origin-side TLS handshake timing. Previously, only client-side TLS timing was available via TS_MILESTONE_TLS_HANDSHAKE_START/END, making it impossible to measure origin TLS handshake overhead in the slow log or via the milestone API.

Changes

New server-side TLS milestones (commit 1)

  • Add TS_MILESTONE_SERVER_TLS_HANDSHAKE_START/END enum values in apidefs.h.in (ABI compatible — appended before TS_MILESTONE_LAST_ENTRY)
  • Capture server TLS timing in HttpSM::state_http_server_open() for both the direct (VC_EVENT_WRITE_COMPLETE) and multiplexed (CONNECT_EVENT_TXN) connection paths
  • Fix: SSLNetVConnection::sslClientHandShakeEvent() was recording TLS handshake start time for outbound connections but never calling _record_tls_handshake_end_time() — outbound TLS end time was always 0
  • Rename slow log field tls_handshakeua_tls_handshake for clarity, add new server_tls_handshake field in logical position after server_connect_end
  • Update LogField.cc milestone-to-string mappings for custom log fields
  • Add Lua plugin milestone constants (TS_LUA_MILESTONE_SERVER_TLS_HANDSHAKE_START/END)
  • Update TSHttpTxnMilestoneGet API documentation
  • Update slow_log_report.pl to parse new field names

Fix difference_msec() milestone check (commit 2)

  • difference_msec() only checked if ms_end == 0 (unset) before returning the missing sentinel. If ms_start was unset but ms_end was set, the subtraction would produce a garbage value. Now checks both ms_start and ms_end for 0.

Use SM_START as base for server_tls_handshake (commit 3)

  • Change server_tls_handshake from a duration to an offset from SM_START, consistent with all other server-side fields in the slow log timeline.

Add comments explaining connection paths (commit 4)

  • Clarify that CONNECT_EVENT_TXN is the multiplexed path (HTTP/2) and VC_EVENT_WRITE_COMPLETE is the direct path (HTTP/1).

Make slow_log_report.pl backward compatible (commit 5)

  • The tls_handshakeua_tls_handshake rename broke parsing of old-format logs. The report script now accepts both field names.

Use pre-remap URL in slow log (commit 6)

  • The slow log was printing the post-remap (origin-facing) URL. Changed to use t_state.unmapped_url (the pre-remap URL) so the log shows the URL the client actually requested.

Behavior Notes

  • When no server TLS handshake occurs (non-TLS origin, connection reuse), the milestones remain 0 and the slow log reports -0.001 (the "missing" sentinel), consistent with other unset milestones.
  • The tls_handshakeua_tls_handshake rename is a slow log text change only — it does not affect ABI.
  • Existing TS_MILESTONE_TLS_HANDSHAKE_START/END enum values and behavior are unchanged.

Testing

  • Build passes (including ASAN build)
  • Manual testing with client-side and server-side TLS verified both milestone pairs populate correctly
  • slow_log_report.pl correctly parses and reports both ua_tls_handshake and server_tls_handshake
  • Verified milestones remain 0 for non-TLS and connection-reuse scenarios

Add TS_MILESTONE_SERVER_TLS_HANDSHAKE_START/END to capture origin-side
TLS handshake timing, complementing the existing client-side
TS_MILESTONE_TLS_HANDSHAKE_START/END milestones.

Changes:
- Add new milestone enum values in apidefs.h.in (ABI compatible -
  appended before TS_MILESTONE_LAST_ENTRY)
- Capture server TLS timing in HttpSM::state_http_server_open() for
  both the direct (VC_EVENT_WRITE_COMPLETE) and multiplexed
  (CONNECT_EVENT_TXN) connection paths
- Fix missing _record_tls_handshake_end_time() call in
  SSLNetVConnection::sslClientHandShakeEvent() - outbound TLS
  handshakes were recording start time but never end time
- Rename slow log field "tls_handshake" to "ua_tls_handshake" for
  clarity and add "server_tls_handshake" field
- Update LogField.cc milestone mappings for custom log fields
- Add Lua plugin milestone constants
- Update API documentation and slow_log_report.pl
Previously, difference_msec() only checked if ms_end was 0 (unset)
before returning the "missing" sentinel value. If ms_start was unset
(0) but ms_end was set, the subtraction would produce a garbage value
equal to the raw nanosecond timestamp of ms_end.

This affects any milestone difference calculation where the start
milestone may not be set, such as server-side milestones on cache
hits where no origin connection was made.

The fix adds a check for ms_start == 0 alongside the existing ms_end
check. This is safe because ink_hrtime values are nanoseconds from a
reference point and are never legitimately 0. The difference_sec()
function inherits this fix since it delegates to difference_msec().
@bryancall bryancall added this to the 10.2.0 milestone Feb 5, 2026
@bryancall bryancall self-assigned this Feb 5, 2026
Change server_tls_handshake from a duration (START to END) to an
offset from SM_START (SM_START to END), consistent with all other
server-side fields in the slow log (server_connect, server_connect_end,
server_first_read, etc.). The TLS duration can be inferred from
server_tls_handshake - server_connect_end.
Clarify that CONNECT_EVENT_TXN is the multiplexed path (e.g. HTTP/2)
where ConnectingEntry creates the session, and VC_EVENT_WRITE_COMPLETE
is the direct path (e.g. HTTP/1) where HttpSM owns the netvc. Both
paths need to capture server TLS handshake timing.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds server-side TLS handshake milestones to Apache Traffic Server, enabling measurement of origin TLS handshake overhead. The PR addresses two main issues: (1) missing visibility into server-side TLS handshake timing, and (2) bugs in milestone timing capture and calculation.

Changes:

  • Adds TS_MILESTONE_SERVER_TLS_HANDSHAKE_START/END enum values and captures server TLS timing in both direct and multiplexed connection paths
  • Fixes missing TLS handshake end time recording for outbound connections in SSLNetVConnection::sslClientHandShakeEvent()
  • Fixes difference_msec() to check both start and end milestones for 0 before computing difference
  • Renames slow log field tls_handshake to ua_tls_handshake for clarity and adds server_tls_handshake field

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
include/ts/apidefs.h.in Adds TS_MILESTONE_SERVER_TLS_HANDSHAKE_START/END enum values before TS_MILESTONE_LAST_ENTRY (ABI-compatible)
include/proxy/Milestones.h Fixes difference_msec() to check both start and end for zero before subtraction
src/iocore/net/SSLNetVConnection.cc Adds missing _record_tls_handshake_end_time() call for outbound TLS connections
src/proxy/http/HttpSM.cc Captures server TLS milestones in both connection paths (direct and multiplexed); renames slow log field to ua_tls_handshake and adds server_tls_handshake
src/proxy/logging/LogField.cc Adds milestone string mappings for new server TLS milestones with TODO comments for ATS 11 rename
plugins/lua/ts_lua_http_milestone.cc Adds Lua plugin constants for server TLS handshake milestones
doc/developer-guide/api/functions/TSHttpTxnMilestoneGet.en.rst Updates API documentation to clarify client vs. server TLS handshake milestones
doc/admin-guide/plugins/lua.en.rst Documents new Lua milestone constants
tools/slow_log_report.pl Updates regex to parse renamed ua_tls_handshake field and new server_tls_handshake field

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The tls_handshake field was renamed to ua_tls_handshake but the
report script needs to handle both formats so it can parse logs
from before and after the rename.
The slow log was printing the post-remap (origin-facing) URL which
is less useful for debugging since it does not show what the client
actually requested. Use t_state.unmapped_url (the pre-remap URL)
instead, with a fallback to client_request URL if unmapped_url is
not available.
@bryancall bryancall force-pushed the server-tls-milestones branch from b79b159 to 2f0b819 Compare February 6, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant