Skip to content

Commit 6433936

Browse files
0x676e67Copilot
andauthored
feat(tls): record negotiated TLS version (#34)
* feat(tls): add more TLS extension matching * feat(tls): record negotiated TLS version * Update src/server/tracker/inspector/tls/hello.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/server/tracker/info.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/server/tracker/inspector/tls/hello.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6c9353c commit 6433936

3 files changed

Lines changed: 35 additions & 6 deletions

File tree

src/server/tracker/accept.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ where
4040
let (mut stream, service) = acceptor.accept(TlsInspector::new(stream), service).await?;
4141
let mut connect_track = ConnectionTrack::default();
4242
connect_track.set_client_hello(stream.get_mut().0.client_hello());
43+
connect_track.set_tls_version_negotiated(stream.get_ref().1.protocol_version());
4344

4445
let stream = match stream.get_ref().1.alpn_protocol() {
4546
// If ALPN is set to HTTP/2, use Http2Inspector

src/server/tracker/info.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use axum::{
55
http::{header::USER_AGENT, HeaderValue, Method, Request},
66
};
77
use serde::{Serialize, Serializer};
8+
use tokio_rustls::rustls::ProtocolVersion;
89

910
use super::inspector::{ClientHello, Frame, Http1Headers, Http2Frame, LazyClientHello};
1011

@@ -28,6 +29,8 @@ pub struct Http2TrackInfo {
2829
/// Collects TLS, HTTP/1, and HTTP/2 handshake info for tracking.
2930
#[derive(Clone, Default)]
3031
pub struct ConnectionTrack {
32+
/// The TLS protocol version that was negotiated for this connection, if any.
33+
tls_version_negotiated: Option<ProtocolVersion>,
3134
client_hello: Option<LazyClientHello>,
3235
http1_headers: Option<Http1Headers>,
3336
http2_frames: Option<Http2Frame>,
@@ -216,6 +219,12 @@ where
216219
// ==== impl ConnectionTrack ====
217220

218221
impl ConnectionTrack {
222+
/// Set TLS version negotiated during the handshake.
223+
#[inline]
224+
pub fn set_tls_version_negotiated(&mut self, version: Option<ProtocolVersion>) {
225+
self.tls_version_negotiated = version;
226+
}
227+
219228
/// Set TLS client hello
220229
#[inline]
221230
pub fn set_client_hello(&mut self, client_hello: Option<LazyClientHello>) {
@@ -248,17 +257,23 @@ impl TrackInfo {
248257
req: Request<Body>,
249258
connection_track: ConnectionTrack,
250259
) -> TrackInfo {
251-
let headers = req.headers();
260+
let mut tls = connection_track
261+
.client_hello
262+
.and_then(LazyClientHello::parse)
263+
.map(TlsTrackInfo::new);
264+
265+
if let Some(tls) = tls.as_mut() {
266+
tls.0
267+
.set_tls_version_negotiated(connection_track.tls_version_negotiated);
268+
}
269+
252270
let track_info = TrackInfo {
253271
donate: Self::DONATE_URL,
254272
address: addr,
255273
http_version: format!("{:?}", req.version()),
256274
method: req.method().clone(),
257-
user_agent: headers.get(USER_AGENT).cloned(),
258-
tls: connection_track
259-
.client_hello
260-
.and_then(LazyClientHello::parse)
261-
.map(TlsTrackInfo::new),
275+
user_agent: req.headers().get(USER_AGENT).cloned(),
276+
tls,
262277
http1: connection_track.http1_headers.map(Http1TrackInfo::new),
263278
http2: connection_track.http2_frames.and_then(Http2TrackInfo::new),
264279
};

src/server/tracker/inspector/tls/hello.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use serde::Serialize;
44
use tls_parser::{TlsCipherSuite, TlsExtensionType, TlsMessage, TlsMessageHandshake};
5+
use tokio_rustls::rustls::ProtocolVersion;
56

67
use super::{
78
enums::{
@@ -54,6 +55,8 @@ impl LazyClientHello {
5455
pub struct ClientHello {
5556
/// TLS version of message
5657
tls_version: TlsVersion,
58+
/// The final TLS version negotiated during the handshake
59+
tls_version_negotiated: Option<TlsVersion>,
5760
client_random: String,
5861
session_id: Option<String>,
5962
/// A list of compression methods supported by client
@@ -233,6 +236,15 @@ pub struct OidFilter {
233236
}
234237

235238
impl ClientHello {
239+
/// Sets the negotiated TLS version for this `ClientHello`.
240+
///
241+
/// # Parameters
242+
/// - `version`: An `Option<ProtocolVersion>` representing the negotiated TLS version.
243+
/// If `Some`, the version is set; if `None`, no version was negotiated.
244+
pub fn set_tls_version_negotiated(&mut self, version: Option<ProtocolVersion>) {
245+
self.tls_version_negotiated = version.map(u16::from).map(TlsVersion::from);
246+
}
247+
236248
pub fn parse(buf: &[u8]) -> Option<Self> {
237249
let (_, r) = tls_parser::parse_tls_raw_record(buf).ok()?;
238250
let (_, msg_list) = tls_parser::parse_tls_record_with_header(r.data, &r.hdr).ok()?;
@@ -247,6 +259,7 @@ impl ClientHello {
247259

248260
let mut client_hello = ClientHello {
249261
tls_version: TlsVersion::from(payload.version.0),
262+
tls_version_negotiated: None,
250263
client_random: hex::encode(payload.random),
251264
session_id: payload.session_id.map(hex::encode),
252265
compression_algorithms: payload

0 commit comments

Comments
 (0)