-
Notifications
You must be signed in to change notification settings - Fork 851
Add: Server-side TLS handshake milestones and timing fixes #12860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
07e0f9c
9bac89e
d0ab0ac
9ef7b31
16951f2
2f0b819
c50964b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1881,21 +1881,43 @@ HttpSM::state_http_server_open(int event, void *data) | |
| case CONNECT_EVENT_RETRY: | ||
| do_http_server_open(); | ||
| break; | ||
| case CONNECT_EVENT_TXN: | ||
| case CONNECT_EVENT_TXN: { | ||
| // Multiplexed connection path (H2/H3): ConnectingEntry owns the connection and | ||
| // dispatches this event with the PoolableSession once the handshake completes. | ||
| // The HttpSM has no access to the netvc during the handshake, so we copy the | ||
| // timestamps that were recorded in real-time by sslClientHandShakeEvent(). | ||
| // See also VC_EVENT_WRITE_COMPLETE below for the direct (H1) path -- these | ||
| // two paths are mutually exclusive. | ||
| SMDbg(dbg_ctl_http, "Connection handshake complete via CONNECT_EVENT_TXN"); | ||
| if (this->create_server_txn(static_cast<PoolableSession *>(data))) { | ||
| PoolableSession *session = static_cast<PoolableSession *>(data); | ||
| ink_assert(session != nullptr); | ||
| if (auto *netvc = session->get_netvc()) { | ||
| if (auto tbs = netvc->get_service<TLSBasicSupport>()) { | ||
| milestones[TS_MILESTONE_SERVER_TLS_HANDSHAKE_START] = tbs->get_tls_handshake_begin_time(); | ||
| milestones[TS_MILESTONE_SERVER_TLS_HANDSHAKE_END] = tbs->get_tls_handshake_end_time(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sets both milestones after the end time is known. Should we set the start milestone when it starts vs here? As it is, if this code isn't reached, the start milestone won't be set.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The HttpSM doesn't have access to the netvc during the handshake in the multiplexed path — ConnectingEntry owns the connection and dispatches The actual start/end times are captured in real-time at the netvc layer ( Updated the comments to make this clearer. |
||
| } | ||
| } | ||
| if (this->create_server_txn(session)) { | ||
| t_state.current.server->clear_connect_fail(); | ||
| handle_http_server_open(); | ||
| } else { // Failed to create transaction. Maybe too many active transactions already | ||
| // Try again (probably need a bounding counter here) | ||
| do_http_server_open(false); | ||
| } | ||
| return 0; | ||
| } | ||
| case VC_EVENT_READ_COMPLETE: | ||
| case VC_EVENT_WRITE_READY: | ||
| case VC_EVENT_WRITE_COMPLETE: | ||
| // Update the time out to the regular connection timeout. | ||
| // Direct connection path (H1): HttpSM owns the netvc directly. | ||
| // Same milestone copy as CONNECT_EVENT_TXN above -- these two paths are | ||
| // mutually exclusive. Timestamps were recorded in real-time by | ||
| // sslClientHandShakeEvent(); we copy them into milestones here. | ||
| SMDbg(dbg_ctl_http_ss, "Connection handshake complete"); | ||
| if (auto tbs = _netvc->get_service<TLSBasicSupport>()) { | ||
| milestones[TS_MILESTONE_SERVER_TLS_HANDSHAKE_START] = tbs->get_tls_handshake_begin_time(); | ||
| milestones[TS_MILESTONE_SERVER_TLS_HANDSHAKE_END] = tbs->get_tls_handshake_end_time(); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are these set again?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These aren't duplicates — they're two mutually exclusive connection paths. Updated both comments to cross-reference each other and explicitly state they're mutually exclusive. |
||
| this->create_server_txn(this->create_server_session(*_netvc, _netvc_read_buffer, _netvc_reader)); | ||
| t_state.current.server->clear_connect_fail(); | ||
| handle_http_server_open(); | ||
|
|
@@ -7755,12 +7777,21 @@ HttpSM::update_stats() | |
|
|
||
| // print slow requests if the threshold is set (> 0) and if we are over the time threshold | ||
| if (t_state.txn_conf->slow_log_threshold != 0 && ink_hrtime_from_msec(t_state.txn_conf->slow_log_threshold) < total_time) { | ||
| // Use the unmapped (pre-remap) URL so the slow log shows the incoming client URL. | ||
| // unmapped_url may not be valid if the transaction ended before reaching the remap | ||
| // stage (e.g. client timeout during header read, malformed request). In that case | ||
| // fall back to client_request URL which hasn't been remapped yet either. | ||
| char url_string[256] = ""; | ||
| int offset = 0; | ||
| int skip = 0; | ||
|
|
||
| t_state.hdr_info.client_request.url_print(url_string, sizeof(url_string) - 1, &offset, &skip); | ||
| url_string[offset] = 0; // NULL terminate the string | ||
| int url_length = 0; | ||
| if (t_state.unmapped_url.valid()) { | ||
| t_state.unmapped_url.string_get_buf(url_string, sizeof(url_string) - 1, &url_length); | ||
| } else { | ||
| int offset = 0; | ||
| int skip = 0; | ||
| t_state.hdr_info.client_request.url_print(url_string, sizeof(url_string) - 1, &offset, &skip); | ||
| url_length = offset; | ||
| } | ||
| url_string[url_length] = 0; // NULL terminate the string | ||
|
|
||
| // unique id | ||
| char unique_id_string[128] = ""; | ||
|
|
@@ -7799,7 +7830,7 @@ HttpSM::update_stats() | |
| "fd: %d " | ||
| "client state: %d " | ||
| "server state: %d " | ||
| "tls_handshake: %.3f " | ||
| "ua_tls_handshake: %.3f " | ||
| "ua_begin: %.3f " | ||
| "ua_first_read: %.3f " | ||
| "ua_read_header_done: %.3f " | ||
|
|
@@ -7811,6 +7842,7 @@ HttpSM::update_stats() | |
| "dns_lookup_end: %.3f " | ||
| "server_connect: %.3f " | ||
| "server_connect_end: %.3f " | ||
| "server_tls_handshake: %.3f " | ||
| "server_first_read: %.3f " | ||
| "server_read_header_done: %.3f " | ||
| "server_close: %.3f " | ||
|
|
@@ -7834,6 +7866,7 @@ HttpSM::update_stats() | |
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_DNS_LOOKUP_END), | ||
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_SERVER_CONNECT), | ||
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_SERVER_CONNECT_END), | ||
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_SERVER_TLS_HANDSHAKE_END), | ||
bryancall marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_SERVER_FIRST_READ), | ||
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_SERVER_READ_HEADER_DONE), | ||
| milestones.difference_sec(TS_MILESTONE_SM_START, TS_MILESTONE_SERVER_CLOSE), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this added? This function seems to deal with the client side, but the comment mentions outbound connections. And, if this were the outbound side, are we expecting the metrics this function updates to include both sides TLS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming in this file is from the TLS role perspective, not the ATS role.
sslClientHandShakeEvent()handles the outbound side where ATS acts as the TLS client connecting to the origin.sslServerHandShakeEvent()handles the inbound side where ATS acts as the TLS server accepting client connections.The inbound side already records the end time (line 1383), but the outbound side was missing it — this is a bug fix. Without this,
get_tls_handshake_end_time()returns zero when HttpSM tries to copy the timestamps into milestones.I've updated the comment to clarify the naming convention and the two-stage pattern.